mirror of
https://github.com/jakcron/nstool
synced 2024-11-15 02:06:40 +00:00
[nstool] Migrated from sKeyset to KeyConfiguration
This commit is contained in:
parent
67a13b9d34
commit
1fd8f59025
18 changed files with 149 additions and 140 deletions
|
@ -41,9 +41,9 @@ void EsTikProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||||
mOwnIFile = ownIFile;
|
mOwnIFile = ownIFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EsTikProcess::setKeyset(const sKeyset* keyset)
|
void EsTikProcess::setKeyCfg(const KeyConfiguration& keycfg)
|
||||||
{
|
{
|
||||||
mKeyset = keyset;
|
mKeyCfg = keycfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EsTikProcess::setCertificateChain(const fnd::List<nn::pki::SignedData<nn::pki::CertificateBody>>& certs)
|
void EsTikProcess::setCertificateChain(const fnd::List<nn::pki::SignedData<nn::pki::CertificateBody>>& certs)
|
||||||
|
@ -95,7 +95,7 @@ void EsTikProcess::verifyTicket()
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
pki_validator.setRootKey(mKeyset->pki.root_sign_key);
|
pki_validator.setKeyCfg(mKeyCfg);
|
||||||
pki_validator.addCertificates(mCerts);
|
pki_validator.addCertificates(mCerts);
|
||||||
pki_validator.validateSignature(mTik.getBody().getIssuer(), mTik.getSignature().getSignType(), mTik.getSignature().getSignature(), tik_hash);
|
pki_validator.validateSignature(mTik.getBody().getIssuer(), mTik.getSignature().getSignType(), mTik.getSignature().getSignature(), tik_hash);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <nn/pki/SignedData.h>
|
#include <nn/pki/SignedData.h>
|
||||||
#include <nn/pki/CertificateBody.h>
|
#include <nn/pki/CertificateBody.h>
|
||||||
#include <nn/es/TicketBody_V2.h>
|
#include <nn/es/TicketBody_V2.h>
|
||||||
|
#include "KeyConfiguration.h"
|
||||||
#include "nstool.h"
|
#include "nstool.h"
|
||||||
|
|
||||||
class EsTikProcess
|
class EsTikProcess
|
||||||
|
@ -17,7 +18,7 @@ public:
|
||||||
void process();
|
void process();
|
||||||
|
|
||||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||||
void setKeyset(const sKeyset* keyset);
|
void setKeyCfg(const KeyConfiguration& keycfg);
|
||||||
void setCertificateChain(const fnd::List<nn::pki::SignedData<nn::pki::CertificateBody>>& certs);
|
void setCertificateChain(const fnd::List<nn::pki::SignedData<nn::pki::CertificateBody>>& certs);
|
||||||
void setCliOutputMode(CliOutputMode mode);
|
void setCliOutputMode(CliOutputMode mode);
|
||||||
void setVerifyMode(bool verify);
|
void setVerifyMode(bool verify);
|
||||||
|
@ -27,7 +28,7 @@ private:
|
||||||
|
|
||||||
fnd::IFile* mFile;
|
fnd::IFile* mFile;
|
||||||
bool mOwnIFile;
|
bool mOwnIFile;
|
||||||
const sKeyset* mKeyset;
|
KeyConfiguration mKeyCfg;
|
||||||
CliOutputMode mCliOutputMode;
|
CliOutputMode mCliOutputMode;
|
||||||
bool mVerify;
|
bool mVerify;
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,39 @@ KeyConfiguration::KeyConfiguration()
|
||||||
clearNcaExternalKeys();
|
clearNcaExternalKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyConfiguration::KeyConfiguration(const KeyConfiguration& other)
|
||||||
|
{
|
||||||
|
*this = other;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyConfiguration::operator=(const KeyConfiguration& other)
|
||||||
|
{
|
||||||
|
mAcidSignKey = other.mAcidSignKey;
|
||||||
|
mPkg2SignKey = other.mPkg2SignKey;
|
||||||
|
mNcaHeader0SignKey = other.mNcaHeader0SignKey;
|
||||||
|
mXciHeaderSignKey = other.mXciHeaderSignKey;
|
||||||
|
|
||||||
|
mNcaHeaderKey = other.mNcaHeaderKey;
|
||||||
|
mXciHeaderKey = other.mXciHeaderKey;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < kMasterKeyNum; i++)
|
||||||
|
{
|
||||||
|
mPkg2Key[i] = other.mPkg2Key[i];
|
||||||
|
mPkg1Key[i] = other.mPkg1Key[i];
|
||||||
|
mNcaKeyAreaEncryptionKey[0][i] = other.mNcaKeyAreaEncryptionKey[0][i];
|
||||||
|
mNcaKeyAreaEncryptionKey[1][i] = other.mNcaKeyAreaEncryptionKey[1][i];
|
||||||
|
mNcaKeyAreaEncryptionKey[2][i] = other.mNcaKeyAreaEncryptionKey[2][i];
|
||||||
|
mNcaKeyAreaEncryptionKeyHw[0][i] = other.mNcaKeyAreaEncryptionKeyHw[0][i];
|
||||||
|
mNcaKeyAreaEncryptionKeyHw[1][i] = other.mNcaKeyAreaEncryptionKeyHw[1][i];
|
||||||
|
mNcaKeyAreaEncryptionKeyHw[2][i] = other.mNcaKeyAreaEncryptionKeyHw[2][i];
|
||||||
|
mETicketCommonKey[i] = other.mETicketCommonKey[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
mPkiRootKeyList = other.mPkiRootKeyList;
|
||||||
|
|
||||||
|
mNcaExternalContentKeyList = other.mNcaExternalContentKeyList;
|
||||||
|
}
|
||||||
|
|
||||||
void KeyConfiguration::importHactoolGenericKeyfile(const std::string& path)
|
void KeyConfiguration::importHactoolGenericKeyfile(const std::string& path)
|
||||||
{
|
{
|
||||||
clearGeneralKeyConfiguration();
|
clearGeneralKeyConfiguration();
|
||||||
|
|
|
@ -13,6 +13,9 @@ class KeyConfiguration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
KeyConfiguration();
|
KeyConfiguration();
|
||||||
|
KeyConfiguration(const KeyConfiguration& other);
|
||||||
|
|
||||||
|
void operator=(const KeyConfiguration& other);
|
||||||
|
|
||||||
void importHactoolGenericKeyfile(const std::string& path);
|
void importHactoolGenericKeyfile(const std::string& path);
|
||||||
//void importHactoolTitleKeyfile(const std::string& path);
|
//void importHactoolTitleKeyfile(const std::string& path);
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
NcaProcess::NcaProcess() :
|
NcaProcess::NcaProcess() :
|
||||||
mFile(nullptr),
|
mFile(nullptr),
|
||||||
mOwnIFile(false),
|
mOwnIFile(false),
|
||||||
mKeyset(nullptr),
|
|
||||||
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
||||||
mVerify(false),
|
mVerify(false),
|
||||||
mListFs(false)
|
mListFs(false)
|
||||||
|
@ -72,9 +71,9 @@ void NcaProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||||
mOwnIFile = ownIFile;
|
mOwnIFile = ownIFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NcaProcess::setKeyset(const sKeyset* keyset)
|
void NcaProcess::setKeyCfg(const KeyConfiguration& keycfg)
|
||||||
{
|
{
|
||||||
mKeyset = keyset;
|
mKeyCfg = keycfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NcaProcess::setCliOutputMode(CliOutputMode type)
|
void NcaProcess::setCliOutputMode(CliOutputMode type)
|
||||||
|
@ -127,7 +126,9 @@ void NcaProcess::importHeader()
|
||||||
mFile->read((byte_t*)&mHdrBlock, 0, sizeof(nn::hac::sNcaHeaderBlock));
|
mFile->read((byte_t*)&mHdrBlock, 0, sizeof(nn::hac::sNcaHeaderBlock));
|
||||||
|
|
||||||
// decrypt header block
|
// decrypt header block
|
||||||
nn::hac::NcaUtils::decryptNcaHeader((byte_t*)&mHdrBlock, (byte_t*)&mHdrBlock, mKeyset->nca.header_key);
|
fnd::aes::sAesXts128Key header_key;
|
||||||
|
mKeyCfg.getNcaHeaderKey(header_key);
|
||||||
|
nn::hac::NcaUtils::decryptNcaHeader((byte_t*)&mHdrBlock, (byte_t*)&mHdrBlock, header_key);
|
||||||
|
|
||||||
// generate header hash
|
// generate header hash
|
||||||
fnd::sha::Sha256((byte_t*)&mHdrBlock.header, sizeof(nn::hac::sNcaHeader), mHdrHash.bytes);
|
fnd::sha::Sha256((byte_t*)&mHdrBlock.header, sizeof(nn::hac::sNcaHeader), mHdrHash.bytes);
|
||||||
|
@ -149,23 +150,31 @@ void NcaProcess::generateNcaBodyEncryptionKeys()
|
||||||
byte_t keak_index = mHdr.getKaekIndex();
|
byte_t keak_index = mHdr.getKaekIndex();
|
||||||
|
|
||||||
// process key area
|
// process key area
|
||||||
sKeys::sKeyAreaKey keak;
|
sKeys::sKeyAreaKey kak;
|
||||||
|
fnd::aes::sAes128Key key_area_enc_key;
|
||||||
for (size_t i = 0; i < nn::hac::nca::kAesKeyNum; i++)
|
for (size_t i = 0; i < nn::hac::nca::kAesKeyNum; i++)
|
||||||
{
|
{
|
||||||
if (mHdr.getEncAesKeys()[i] != zero_aesctr_key)
|
if (mHdr.getEncAesKeys()[i] != zero_aesctr_key)
|
||||||
{
|
{
|
||||||
keak.index = (byte_t)i;
|
kak.index = (byte_t)i;
|
||||||
keak.enc = mHdr.getEncAesKeys()[i];
|
kak.enc = mHdr.getEncAesKeys()[i];
|
||||||
if (i < 4 && mKeyset->nca.key_area_key[keak_index][masterkey_rev] != zero_aesctr_key)
|
// key[0-3]
|
||||||
|
if (i < 4 && mKeyCfg.getNcaKeyAreaEncryptionKey(masterkey_rev, keak_index, key_area_enc_key) == true)
|
||||||
{
|
{
|
||||||
keak.decrypted = true;
|
kak.decrypted = true;
|
||||||
nn::hac::AesKeygen::generateKey(keak.dec.key, keak.enc.key, mKeyset->nca.key_area_key[keak_index][masterkey_rev].key);
|
nn::hac::AesKeygen::generateKey(kak.dec.key, kak.enc.key, key_area_enc_key.key);
|
||||||
|
}
|
||||||
|
// key[4]
|
||||||
|
else if (i == 4 && mKeyCfg.getNcaKeyAreaEncryptionKeyHw(masterkey_rev, keak_index, key_area_enc_key) == true)
|
||||||
|
{
|
||||||
|
kak.decrypted = true;
|
||||||
|
nn::hac::AesKeygen::generateKey(kak.dec.key, kak.enc.key, key_area_enc_key.key);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
keak.decrypted = false;
|
kak.decrypted = false;
|
||||||
}
|
}
|
||||||
mBodyKeys.keak_list.addElement(keak);
|
mBodyKeys.keak_list.addElement(kak);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,21 +185,19 @@ void NcaProcess::generateNcaBodyEncryptionKeys()
|
||||||
// if this has a rights id, the key needs to be sourced from a ticket
|
// if this has a rights id, the key needs to be sourced from a ticket
|
||||||
if (mHdr.hasRightsId() == true)
|
if (mHdr.hasRightsId() == true)
|
||||||
{
|
{
|
||||||
// if the titlekey_kek is available
|
fnd::aes::sAes128Key tmp_key;
|
||||||
if (mKeyset->ticket.titlekey_kek[masterkey_rev] != zero_aesctr_key)
|
if (mKeyCfg.getNcaExternalContentKey(mHdr.getRightsId(), tmp_key) == true)
|
||||||
{
|
{
|
||||||
// the title key is provided (sourced from ticket)
|
mBodyKeys.aes_ctr = tmp_key;
|
||||||
if (mKeyset->nca.manual_title_key_aesctr != zero_aesctr_key)
|
|
||||||
{
|
|
||||||
nn::hac::AesKeygen::generateKey(mBodyKeys.aes_ctr.var.key, mKeyset->nca.manual_title_key_aesctr.key, mKeyset->ticket.titlekey_kek[masterkey_rev].key);
|
|
||||||
mBodyKeys.aes_ctr.isSet = true;
|
|
||||||
}
|
}
|
||||||
if (mKeyset->nca.manual_title_key_aesxts != zero_aesxts_key)
|
else if (mKeyCfg.getNcaExternalContentKey(kDummyRightsIdForUserTitleKey, tmp_key) == true)
|
||||||
{
|
{
|
||||||
nn::hac::AesKeygen::generateKey(mBodyKeys.aes_xts.var.key[0], mKeyset->nca.manual_title_key_aesxts.key[0], mKeyset->ticket.titlekey_kek[masterkey_rev].key);
|
fnd::aes::sAes128Key common_key;
|
||||||
nn::hac::AesKeygen::generateKey(mBodyKeys.aes_xts.var.key[1], mKeyset->nca.manual_title_key_aesxts.key[1], mKeyset->ticket.titlekey_kek[masterkey_rev].key);
|
if (mKeyCfg.getETicketCommonKey(masterkey_rev, common_key) == true)
|
||||||
mBodyKeys.aes_xts.isSet = true;
|
{
|
||||||
|
nn::hac::AesKeygen::generateKey(tmp_key.key, tmp_key.key, common_key.key);
|
||||||
}
|
}
|
||||||
|
mBodyKeys.aes_ctr = tmp_key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// otherwise decrypt key area
|
// otherwise decrypt key area
|
||||||
|
@ -225,15 +232,13 @@ void NcaProcess::generateNcaBodyEncryptionKeys()
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the keys weren't generated, check if the keys were supplied by the user
|
// if the keys weren't generated, check if the keys were supplied by the user
|
||||||
if (mBodyKeys.aes_ctr.isSet == false && mKeyset->nca.manual_body_key_aesctr != zero_aesctr_key)
|
if (mBodyKeys.aes_ctr.isSet == false)
|
||||||
{
|
{
|
||||||
mBodyKeys.aes_ctr = mKeyset->nca.manual_body_key_aesctr;
|
if (mKeyCfg.getNcaExternalContentKey(kDummyRightsIdForUserBodyKey, mBodyKeys.aes_ctr.var) == true)
|
||||||
}
|
mBodyKeys.aes_ctr.isSet = true;
|
||||||
if (mBodyKeys.aes_xts.isSet == false && mKeyset->nca.manual_body_key_aesxts != zero_aesxts_key)
|
|
||||||
{
|
|
||||||
mBodyKeys.aes_xts = mKeyset->nca.manual_body_key_aesxts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (_HAS_BIT(mCliOutputMode, OUTPUT_KEY_DATA))
|
if (_HAS_BIT(mCliOutputMode, OUTPUT_KEY_DATA))
|
||||||
{
|
{
|
||||||
if (mBodyKeys.aes_ctr.isSet)
|
if (mBodyKeys.aes_ctr.isSet)
|
||||||
|
@ -365,7 +370,9 @@ void NcaProcess::generatePartitionConfiguration()
|
||||||
void NcaProcess::validateNcaSignatures()
|
void NcaProcess::validateNcaSignatures()
|
||||||
{
|
{
|
||||||
// validate signature[0]
|
// validate signature[0]
|
||||||
if (fnd::rsa::pss::rsaVerify(mKeyset->nca.header_sign_key, fnd::sha::HASH_SHA256, mHdrHash.bytes, mHdrBlock.signature_main) != 0)
|
fnd::rsa::sRsa2048Key sign0_key;
|
||||||
|
mKeyCfg.getNcaHeader0SignKey(sign0_key);
|
||||||
|
if (fnd::rsa::pss::rsaVerify(sign0_key, fnd::sha::HASH_SHA256, mHdrHash.bytes, mHdrBlock.signature_main) != 0)
|
||||||
{
|
{
|
||||||
std::cout << "[WARNING] NCA Header Main Signature: FAIL" << std::endl;
|
std::cout << "[WARNING] NCA Header Main Signature: FAIL" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <fnd/SimpleFile.h>
|
#include <fnd/SimpleFile.h>
|
||||||
#include <nn/hac/NcaHeader.h>
|
#include <nn/hac/NcaHeader.h>
|
||||||
#include "HashTreeMeta.h"
|
#include "HashTreeMeta.h"
|
||||||
|
#include "KeyConfiguration.h"
|
||||||
|
|
||||||
|
|
||||||
#include "nstool.h"
|
#include "nstool.h"
|
||||||
|
@ -18,7 +19,7 @@ public:
|
||||||
|
|
||||||
// generic
|
// generic
|
||||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||||
void setKeyset(const sKeyset* keyset);
|
void setKeyCfg(const KeyConfiguration& keycfg);
|
||||||
void setCliOutputMode(CliOutputMode type);
|
void setCliOutputMode(CliOutputMode type);
|
||||||
void setVerifyMode(bool verify);
|
void setVerifyMode(bool verify);
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ private:
|
||||||
// user options
|
// user options
|
||||||
fnd::IFile* mFile;
|
fnd::IFile* mFile;
|
||||||
bool mOwnIFile;
|
bool mOwnIFile;
|
||||||
const sKeyset* mKeyset;
|
KeyConfiguration mKeyCfg;
|
||||||
CliOutputMode mCliOutputMode;
|
CliOutputMode mCliOutputMode;
|
||||||
bool mVerify;
|
bool mVerify;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
NpdmProcess::NpdmProcess() :
|
NpdmProcess::NpdmProcess() :
|
||||||
mFile(nullptr),
|
mFile(nullptr),
|
||||||
mOwnIFile(false),
|
mOwnIFile(false),
|
||||||
mKeyset(nullptr),
|
|
||||||
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
||||||
mVerify(false)
|
mVerify(false)
|
||||||
{
|
{
|
||||||
|
@ -57,9 +56,9 @@ void NpdmProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||||
mOwnIFile = ownIFile;
|
mOwnIFile = ownIFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NpdmProcess::setKeyset(const sKeyset* keyset)
|
void NpdmProcess::setKeyCfg(const KeyConfiguration& keycfg)
|
||||||
{
|
{
|
||||||
mKeyset = keyset;
|
mKeyCfg = keycfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NpdmProcess::setCliOutputMode(CliOutputMode type)
|
void NpdmProcess::setCliOutputMode(CliOutputMode type)
|
||||||
|
@ -95,7 +94,11 @@ void NpdmProcess::importNpdm()
|
||||||
void NpdmProcess::validateAcidSignature(const nn::hac::AccessControlInfoDescBinary& acid)
|
void NpdmProcess::validateAcidSignature(const nn::hac::AccessControlInfoDescBinary& acid)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
acid.validateSignature(mKeyset->acid_sign_key);
|
fnd::rsa::sRsa2048Key acid_sign_key;
|
||||||
|
if (mKeyCfg.getAcidSignKey(acid_sign_key) != true)
|
||||||
|
throw fnd::Exception();
|
||||||
|
|
||||||
|
acid.validateSignature(acid_sign_key);
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
std::cout << "[WARNING] ACID Signature: FAIL" << std::endl;
|
std::cout << "[WARNING] ACID Signature: FAIL" << std::endl;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <fnd/types.h>
|
#include <fnd/types.h>
|
||||||
#include <fnd/IFile.h>
|
#include <fnd/IFile.h>
|
||||||
#include <nn/hac/NpdmBinary.h>
|
#include <nn/hac/NpdmBinary.h>
|
||||||
|
#include "KeyConfiguration.h"
|
||||||
|
|
||||||
#include "nstool.h"
|
#include "nstool.h"
|
||||||
|
|
||||||
|
@ -15,7 +16,7 @@ public:
|
||||||
void process();
|
void process();
|
||||||
|
|
||||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||||
void setKeyset(const sKeyset* keyset);
|
void setKeyCfg(const KeyConfiguration& keycfg);
|
||||||
void setCliOutputMode(CliOutputMode type);
|
void setCliOutputMode(CliOutputMode type);
|
||||||
void setVerifyMode(bool verify);
|
void setVerifyMode(bool verify);
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ private:
|
||||||
|
|
||||||
fnd::IFile* mFile;
|
fnd::IFile* mFile;
|
||||||
bool mOwnIFile;
|
bool mOwnIFile;
|
||||||
const sKeyset* mKeyset;
|
KeyConfiguration mKeyCfg;
|
||||||
CliOutputMode mCliOutputMode;
|
CliOutputMode mCliOutputMode;
|
||||||
bool mVerify;
|
bool mVerify;
|
||||||
|
|
||||||
|
|
|
@ -39,9 +39,9 @@ void PkiCertProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||||
mOwnIFile = ownIFile;
|
mOwnIFile = ownIFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PkiCertProcess::setKeyset(const sKeyset* keyset)
|
void PkiCertProcess::setKeyCfg(const KeyConfiguration& keycfg)
|
||||||
{
|
{
|
||||||
mKeyset = keyset;
|
mKeyCfg = keycfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PkiCertProcess::setCliOutputMode(CliOutputMode mode)
|
void PkiCertProcess::setCliOutputMode(CliOutputMode mode)
|
||||||
|
@ -80,7 +80,7 @@ void PkiCertProcess::validateCerts()
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
pki.setRootKey(mKeyset->pki.root_sign_key);
|
pki.setKeyCfg(mKeyCfg);
|
||||||
pki.addCertificates(mCert);
|
pki.addCertificates(mCert);
|
||||||
}
|
}
|
||||||
catch (const fnd::Exception& e)
|
catch (const fnd::Exception& e)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <fnd/Vec.h>
|
#include <fnd/Vec.h>
|
||||||
#include <nn/pki/SignedData.h>
|
#include <nn/pki/SignedData.h>
|
||||||
#include <nn/pki/CertificateBody.h>
|
#include <nn/pki/CertificateBody.h>
|
||||||
|
#include "KeyConfiguration.h"
|
||||||
#include "nstool.h"
|
#include "nstool.h"
|
||||||
|
|
||||||
class PkiCertProcess
|
class PkiCertProcess
|
||||||
|
@ -17,7 +18,7 @@ public:
|
||||||
void process();
|
void process();
|
||||||
|
|
||||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||||
void setKeyset(const sKeyset* keyset);
|
void setKeyCfg(const KeyConfiguration& keycfg);
|
||||||
void setCliOutputMode(CliOutputMode type);
|
void setCliOutputMode(CliOutputMode type);
|
||||||
void setVerifyMode(bool verify);
|
void setVerifyMode(bool verify);
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ private:
|
||||||
|
|
||||||
fnd::IFile* mFile;
|
fnd::IFile* mFile;
|
||||||
bool mOwnIFile;
|
bool mOwnIFile;
|
||||||
const sKeyset* mKeyset;
|
KeyConfiguration mKeyCfg;
|
||||||
CliOutputMode mCliOutputMode;
|
CliOutputMode mCliOutputMode;
|
||||||
bool mVerify;
|
bool mVerify;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ PkiValidator::PkiValidator()
|
||||||
clearCertificates();
|
clearCertificates();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PkiValidator::setRootKey(const fnd::rsa::sRsa4096Key& root_key)
|
void PkiValidator::setKeyCfg(const KeyConfiguration& keycfg)
|
||||||
{
|
{
|
||||||
// save a copy of the certificate bank
|
// save a copy of the certificate bank
|
||||||
fnd::List<nn::pki::SignedData<nn::pki::CertificateBody>> old_certs = mCertificateBank;
|
fnd::List<nn::pki::SignedData<nn::pki::CertificateBody>> old_certs = mCertificateBank;
|
||||||
|
@ -18,7 +18,7 @@ void PkiValidator::setRootKey(const fnd::rsa::sRsa4096Key& root_key)
|
||||||
mCertificateBank.clear();
|
mCertificateBank.clear();
|
||||||
|
|
||||||
// overwrite the root key
|
// overwrite the root key
|
||||||
mRootKey = root_key;
|
mKeyCfg = keycfg;
|
||||||
|
|
||||||
// if there were certificates before, reimport them (so they are checked against the new root key)
|
// if there were certificates before, reimport them (so they are checked against the new root key)
|
||||||
if (old_certs.size() > 0)
|
if (old_certs.size() > 0)
|
||||||
|
@ -96,13 +96,28 @@ void PkiValidator::validateSignature(const std::string& issuer, nn::pki::sign::S
|
||||||
int sig_validate_res = -1;
|
int sig_validate_res = -1;
|
||||||
|
|
||||||
// special case if signed by Root
|
// special case if signed by Root
|
||||||
if (issuer == nn::pki::sign::kRootIssuerStr)
|
if (issuer.find('-', 0) == std::string::npos)
|
||||||
{
|
{
|
||||||
if (sign_algo != nn::pki::sign::SIGN_ALGO_RSA4096)
|
fnd::rsa::sRsa4096Key rsa4096_pub;
|
||||||
|
fnd::rsa::sRsa2048Key rsa2048_pub;
|
||||||
|
fnd::ecdsa::sEcdsa240Key ecdsa_pub;
|
||||||
|
|
||||||
|
if (mKeyCfg.getPkiRootSignKey(issuer, rsa4096_pub) == true && sign_algo == nn::pki::sign::SIGN_ALGO_RSA4096)
|
||||||
{
|
{
|
||||||
throw fnd::Exception(kModuleName, "Issued by Root, but does not have a RSA4096 signature");
|
sig_validate_res = fnd::rsa::pkcs::rsaVerify(rsa4096_pub, getCryptoHashAlgoFromEsSignHashAlgo(hash_algo), hash.data(), signature.data());
|
||||||
|
}
|
||||||
|
else if (mKeyCfg.getPkiRootSignKey(issuer, rsa2048_pub) == true && sign_algo == nn::pki::sign::SIGN_ALGO_RSA2048)
|
||||||
|
{
|
||||||
|
sig_validate_res = fnd::rsa::pkcs::rsaVerify(rsa2048_pub, getCryptoHashAlgoFromEsSignHashAlgo(hash_algo), hash.data(), signature.data());
|
||||||
|
}
|
||||||
|
else if (mKeyCfg.getPkiRootSignKey(issuer, ecdsa_pub) == true && sign_algo == nn::pki::sign::SIGN_ALGO_ECDSA240)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "ECDSA signatures are not supported");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "Public key for issuer \"" + issuer + "\" does not exist.");
|
||||||
}
|
}
|
||||||
sig_validate_res = fnd::rsa::pkcs::rsaVerify(mRootKey, getCryptoHashAlgoFromEsSignHashAlgo(hash_algo), hash.data(), signature.data());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,13 +6,14 @@
|
||||||
#include <nn/pki/SignedData.h>
|
#include <nn/pki/SignedData.h>
|
||||||
#include <nn/pki/CertificateBody.h>
|
#include <nn/pki/CertificateBody.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "KeyConfiguration.h"
|
||||||
|
|
||||||
class PkiValidator
|
class PkiValidator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PkiValidator();
|
PkiValidator();
|
||||||
|
|
||||||
void setRootKey(const fnd::rsa::sRsa4096Key& root_key);
|
void setKeyCfg(const KeyConfiguration& keycfg);
|
||||||
void addCertificates(const fnd::List<nn::pki::SignedData<nn::pki::CertificateBody>>& certs);
|
void addCertificates(const fnd::List<nn::pki::SignedData<nn::pki::CertificateBody>>& certs);
|
||||||
void addCertificate(const nn::pki::SignedData<nn::pki::CertificateBody>& cert);
|
void addCertificate(const nn::pki::SignedData<nn::pki::CertificateBody>& cert);
|
||||||
void clearCertificates();
|
void clearCertificates();
|
||||||
|
@ -22,8 +23,7 @@ public:
|
||||||
private:
|
private:
|
||||||
const std::string kModuleName = "NNPkiValidator";
|
const std::string kModuleName = "NNPkiValidator";
|
||||||
|
|
||||||
|
KeyConfiguration mKeyCfg;
|
||||||
fnd::rsa::sRsa4096Key mRootKey;
|
|
||||||
fnd::List<nn::pki::SignedData<nn::pki::CertificateBody>> mCertificateBank;
|
fnd::List<nn::pki::SignedData<nn::pki::CertificateBody>> mCertificateBank;
|
||||||
|
|
||||||
void makeCertIdent(const nn::pki::SignedData<nn::pki::CertificateBody>& cert, std::string& ident) const;
|
void makeCertIdent(const nn::pki::SignedData<nn::pki::CertificateBody>& cert, std::string& ident) const;
|
||||||
|
|
|
@ -96,9 +96,9 @@ const std::string UserSettings::getInputPath() const
|
||||||
return mInputPath;
|
return mInputPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sKeyset& UserSettings::getKeyset() const
|
const KeyConfiguration& UserSettings::getKeyCfg() const
|
||||||
{
|
{
|
||||||
return mKeyset;
|
return mKeyCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileType UserSettings::getFileType() const
|
FileType UserSettings::getFileType() const
|
||||||
|
@ -386,8 +386,6 @@ void UserSettings::populateCmdArgs(const std::vector<std::string>& arg_list, sCm
|
||||||
|
|
||||||
void UserSettings::populateKeyset(sCmdArgs& args)
|
void UserSettings::populateKeyset(sCmdArgs& args)
|
||||||
{
|
{
|
||||||
memset((void*)&mKeyset, 0, sizeof(sKeyset));
|
|
||||||
|
|
||||||
if (args.keyset_path.isSet)
|
if (args.keyset_path.isSet)
|
||||||
{
|
{
|
||||||
mKeyCfg.importHactoolGenericKeyfile(*args.keyset_path);
|
mKeyCfg.importHactoolGenericKeyfile(*args.keyset_path);
|
||||||
|
@ -413,22 +411,7 @@ void UserSettings::populateKeyset(sCmdArgs& args)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mKeyCfg.getPkiRootSignKey(nn::pki::sign::kRootIssuerStr, mKeyset.pki.root_sign_key);
|
|
||||||
mKeyCfg.getAcidSignKey(mKeyset.acid_sign_key);
|
|
||||||
mKeyCfg.getNcaHeader0SignKey(mKeyset.nca.header_sign_key);
|
|
||||||
mKeyCfg.getNcaHeaderKey(mKeyset.nca.header_key);
|
|
||||||
mKeyCfg.getXciHeaderSignKey(mKeyset.xci.header_sign_key);
|
|
||||||
mKeyCfg.getXciHeaderKey(mKeyset.xci.header_key);
|
|
||||||
mKeyCfg.getPkg2SignKey(mKeyset.package2_sign_key);
|
|
||||||
for (size_t mkeyidx = 0; mkeyidx < 32; mkeyidx++)
|
|
||||||
{
|
|
||||||
mKeyCfg.getPkg1Key(mkeyidx, mKeyset.package1_key[mkeyidx]);
|
|
||||||
mKeyCfg.getPkg2Key(mkeyidx, mKeyset.package1_key[mkeyidx]);
|
|
||||||
mKeyCfg.getNcaKeyAreaEncryptionKey(mkeyidx, 0, mKeyset.nca.key_area_key[0][mkeyidx]);
|
|
||||||
mKeyCfg.getNcaKeyAreaEncryptionKey(mkeyidx, 1, mKeyset.nca.key_area_key[1][mkeyidx]);
|
|
||||||
mKeyCfg.getNcaKeyAreaEncryptionKey(mkeyidx, 2, mKeyset.nca.key_area_key[2][mkeyidx]);
|
|
||||||
mKeyCfg.getETicketCommonKey(mkeyidx, mKeyset.ticket.titlekey_kek[mkeyidx]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.nca_bodykey.isSet)
|
if (args.nca_bodykey.isSet)
|
||||||
{
|
{
|
||||||
|
@ -503,7 +486,7 @@ void UserSettings::populateKeyset(sCmdArgs& args)
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
pki_validator.setRootKey(mKeyset.pki.root_sign_key);
|
pki_validator.setKeyCfg(mKeyCfg);
|
||||||
pki_validator.addCertificates(mCertChain);
|
pki_validator.addCertificates(mCertChain);
|
||||||
pki_validator.validateSignature(tik.getBody().getIssuer(), tik.getSignature().getSignType(), tik.getSignature().getSignature(), tik_hash);
|
pki_validator.validateSignature(tik.getBody().getIssuer(), tik.getSignature().getSignType(), tik.getSignature().getSignature(), tik_hash);
|
||||||
}
|
}
|
||||||
|
@ -519,7 +502,6 @@ void UserSettings::populateKeyset(sCmdArgs& args)
|
||||||
{
|
{
|
||||||
fnd::aes::sAes128Key enc_title_key;
|
fnd::aes::sAes128Key enc_title_key;
|
||||||
memcpy(enc_title_key.key, tik.getBody().getEncTitleKey(), 16);
|
memcpy(enc_title_key.key, tik.getBody().getEncTitleKey(), 16);
|
||||||
mKeyCfg.addNcaExternalContentKey(kDummyRightsIdForUserTitleKey, enc_title_key);
|
|
||||||
fnd::aes::sAes128Key common_key, external_content_key;
|
fnd::aes::sAes128Key common_key, external_content_key;
|
||||||
if (mKeyCfg.getETicketCommonKey(nn::hac::NcaUtils::getMasterKeyRevisionFromKeyGeneration(tik.getBody().getCommonKeyId()), common_key) == true)
|
if (mKeyCfg.getETicketCommonKey(nn::hac::NcaUtils::getMasterKeyRevisionFromKeyGeneration(tik.getBody().getCommonKeyId()), common_key) == true)
|
||||||
{
|
{
|
||||||
|
@ -536,10 +518,6 @@ void UserSettings::populateKeyset(sCmdArgs& args)
|
||||||
std::cout << "[WARNING] Titlekey not imported from ticket because it is personalised" << std::endl;
|
std::cout << "[WARNING] Titlekey not imported from ticket because it is personalised" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// replicate keys into old keyset
|
|
||||||
mKeyCfg.getNcaExternalContentKey(kDummyRightsIdForUserBodyKey, mKeyset.nca.manual_body_key_aesctr);
|
|
||||||
mKeyCfg.getNcaExternalContentKey(kDummyRightsIdForUserTitleKey, mKeyset.nca.manual_title_key_aesctr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserSettings::populateUserSettings(sCmdArgs& args)
|
void UserSettings::populateUserSettings(sCmdArgs& args)
|
||||||
|
@ -721,7 +699,9 @@ bool UserSettings::determineValidNcaFromSample(const fnd::Vec<byte_t>& sample) c
|
||||||
if (sample.size() < nn::hac::nca::kHeaderSize)
|
if (sample.size() < nn::hac::nca::kHeaderSize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
nn::hac::NcaUtils::decryptNcaHeader(sample.data(), nca_raw, mKeyset.nca.header_key);
|
fnd::aes::sAesXts128Key header_key;
|
||||||
|
mKeyCfg.getNcaHeaderKey(header_key);
|
||||||
|
nn::hac::NcaUtils::decryptNcaHeader(sample.data(), nca_raw, header_key);
|
||||||
|
|
||||||
if (nca_header->st_magic.get() != nn::hac::nca::kNca2StructMagic && nca_header->st_magic.get() != nn::hac::nca::kNca3StructMagic)
|
if (nca_header->st_magic.get() != nn::hac::nca::kNca2StructMagic && nca_header->st_magic.get() != nn::hac::nca::kNca3StructMagic)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -21,7 +21,6 @@ public:
|
||||||
// generic options
|
// generic options
|
||||||
const std::string getInputPath() const;
|
const std::string getInputPath() const;
|
||||||
const KeyConfiguration& getKeyCfg() const;
|
const KeyConfiguration& getKeyCfg() const;
|
||||||
const sKeyset& getKeyset() const;
|
|
||||||
FileType getFileType() const;
|
FileType getFileType() const;
|
||||||
bool isVerifyFile() const;
|
bool isVerifyFile() const;
|
||||||
CliOutputMode getCliOutputMode() const;
|
CliOutputMode getCliOutputMode() const;
|
||||||
|
@ -90,7 +89,6 @@ private:
|
||||||
|
|
||||||
std::string mInputPath;
|
std::string mInputPath;
|
||||||
FileType mFileType;
|
FileType mFileType;
|
||||||
sKeyset mKeyset;
|
|
||||||
KeyConfiguration mKeyCfg;
|
KeyConfiguration mKeyCfg;
|
||||||
bool mVerifyFile;
|
bool mVerifyFile;
|
||||||
CliOutputMode mOutputMode;
|
CliOutputMode mOutputMode;
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
XciProcess::XciProcess() :
|
XciProcess::XciProcess() :
|
||||||
mFile(nullptr),
|
mFile(nullptr),
|
||||||
mOwnIFile(false),
|
mOwnIFile(false),
|
||||||
mKeyset(nullptr),
|
|
||||||
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
||||||
mVerify(false),
|
mVerify(false),
|
||||||
mListFs(false),
|
mListFs(false),
|
||||||
|
@ -50,9 +49,9 @@ void XciProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||||
mOwnIFile = ownIFile;
|
mOwnIFile = ownIFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XciProcess::setKeyset(const sKeyset* keyset)
|
void XciProcess::setKeyCfg(const KeyConfiguration& keycfg)
|
||||||
{
|
{
|
||||||
mKeyset = keyset;
|
mKeyCfg = keycfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XciProcess::setCliOutputMode(CliOutputMode type)
|
void XciProcess::setCliOutputMode(CliOutputMode type)
|
||||||
|
@ -89,7 +88,10 @@ void XciProcess::importHeader()
|
||||||
|
|
||||||
// allocate memory for and decrypt sXciHeader
|
// allocate memory for and decrypt sXciHeader
|
||||||
scratch.alloc(sizeof(nn::hac::sXciHeader));
|
scratch.alloc(sizeof(nn::hac::sXciHeader));
|
||||||
nn::hac::XciUtils::decryptXciHeader((const byte_t*)&mHdrPage.header, scratch.data(), mKeyset->xci.header_key.key);
|
|
||||||
|
fnd::aes::sAes128Key header_key;
|
||||||
|
mKeyCfg.getXciHeaderKey(header_key);
|
||||||
|
nn::hac::XciUtils::decryptXciHeader((const byte_t*)&mHdrPage.header, scratch.data(), header_key.key);
|
||||||
|
|
||||||
// deserialise header
|
// deserialise header
|
||||||
mHdr.fromBytes(scratch.data(), scratch.size());
|
mHdr.fromBytes(scratch.data(), scratch.size());
|
||||||
|
@ -198,9 +200,11 @@ bool XciProcess::validateRegionOfFile(size_t offset, size_t len, const byte_t* t
|
||||||
|
|
||||||
void XciProcess::validateXciSignature()
|
void XciProcess::validateXciSignature()
|
||||||
{
|
{
|
||||||
|
fnd::rsa::sRsa2048Key header_sign_key;
|
||||||
fnd::sha::sSha256Hash calc_hash;
|
fnd::sha::sSha256Hash calc_hash;
|
||||||
fnd::sha::Sha256((byte_t*)&mHdrPage.header, sizeof(nn::hac::sXciHeader), calc_hash.bytes);
|
fnd::sha::Sha256((byte_t*)&mHdrPage.header, sizeof(nn::hac::sXciHeader), calc_hash.bytes);
|
||||||
if (fnd::rsa::pkcs::rsaVerify(mKeyset->xci.header_sign_key, fnd::sha::HASH_SHA256, calc_hash.bytes, mHdrPage.signature) != 0)
|
mKeyCfg.getXciHeaderSignKey(header_sign_key);
|
||||||
|
if (fnd::rsa::pkcs::rsaVerify(header_sign_key, fnd::sha::HASH_SHA256, calc_hash.bytes, mHdrPage.signature) != 0)
|
||||||
{
|
{
|
||||||
std::cout << "[WARNING] XCI Header Signature: FAIL" << std::endl;
|
std::cout << "[WARNING] XCI Header Signature: FAIL" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,10 @@
|
||||||
#include <fnd/IFile.h>
|
#include <fnd/IFile.h>
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <nn/hac/XciHeader.h>
|
#include <nn/hac/XciHeader.h>
|
||||||
|
#include "KeyConfiguration.h"
|
||||||
#include "nstool.h"
|
|
||||||
|
|
||||||
#include "PfsProcess.h"
|
#include "PfsProcess.h"
|
||||||
|
|
||||||
|
#include "nstool.h"
|
||||||
|
|
||||||
class XciProcess
|
class XciProcess
|
||||||
{
|
{
|
||||||
|
@ -20,7 +19,7 @@ public:
|
||||||
|
|
||||||
// generic
|
// generic
|
||||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||||
void setKeyset(const sKeyset* keyset);
|
void setKeyCfg(const KeyConfiguration& keycfg);
|
||||||
void setCliOutputMode(CliOutputMode type);
|
void setCliOutputMode(CliOutputMode type);
|
||||||
void setVerifyMode(bool verify);
|
void setVerifyMode(bool verify);
|
||||||
|
|
||||||
|
@ -34,7 +33,7 @@ private:
|
||||||
|
|
||||||
fnd::IFile* mFile;
|
fnd::IFile* mFile;
|
||||||
bool mOwnIFile;
|
bool mOwnIFile;
|
||||||
const sKeyset* mKeyset;
|
KeyConfiguration mKeyCfg;
|
||||||
CliOutputMode mCliOutputMode;
|
CliOutputMode mCliOutputMode;
|
||||||
bool mVerify;
|
bool mVerify;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
xci.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
xci.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||||
|
|
||||||
xci.setKeyset(&user_set.getKeyset());
|
xci.setKeyCfg(user_set.getKeyCfg());
|
||||||
xci.setCliOutputMode(user_set.getCliOutputMode());
|
xci.setCliOutputMode(user_set.getCliOutputMode());
|
||||||
xci.setVerifyMode(user_set.isVerifyFile());
|
xci.setVerifyMode(user_set.isVerifyFile());
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ int main(int argc, char** argv)
|
||||||
NcaProcess nca;
|
NcaProcess nca;
|
||||||
|
|
||||||
nca.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
nca.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||||
nca.setKeyset(&user_set.getKeyset());
|
nca.setKeyCfg(user_set.getKeyCfg());
|
||||||
nca.setCliOutputMode(user_set.getCliOutputMode());
|
nca.setCliOutputMode(user_set.getCliOutputMode());
|
||||||
nca.setVerifyMode(user_set.isVerifyFile());
|
nca.setVerifyMode(user_set.isVerifyFile());
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ int main(int argc, char** argv)
|
||||||
NpdmProcess npdm;
|
NpdmProcess npdm;
|
||||||
|
|
||||||
npdm.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
npdm.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||||
npdm.setKeyset(&user_set.getKeyset());
|
npdm.setKeyCfg(user_set.getKeyCfg());
|
||||||
npdm.setCliOutputMode(user_set.getCliOutputMode());
|
npdm.setCliOutputMode(user_set.getCliOutputMode());
|
||||||
npdm.setVerifyMode(user_set.isVerifyFile());
|
npdm.setVerifyMode(user_set.isVerifyFile());
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ int main(int argc, char** argv)
|
||||||
PkiCertProcess cert;
|
PkiCertProcess cert;
|
||||||
|
|
||||||
cert.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
cert.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||||
cert.setKeyset(&user_set.getKeyset());
|
cert.setKeyCfg(user_set.getKeyCfg());
|
||||||
cert.setCliOutputMode(user_set.getCliOutputMode());
|
cert.setCliOutputMode(user_set.getCliOutputMode());
|
||||||
cert.setVerifyMode(user_set.isVerifyFile());
|
cert.setVerifyMode(user_set.isVerifyFile());
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ int main(int argc, char** argv)
|
||||||
EsTikProcess tik;
|
EsTikProcess tik;
|
||||||
|
|
||||||
tik.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
tik.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||||
tik.setKeyset(&user_set.getKeyset());
|
tik.setKeyCfg(user_set.getKeyCfg());
|
||||||
tik.setCertificateChain(user_set.getCertificateChain());
|
tik.setCertificateChain(user_set.getCertificateChain());
|
||||||
tik.setCliOutputMode(user_set.getCliOutputMode());
|
tik.setCliOutputMode(user_set.getCliOutputMode());
|
||||||
tik.setVerifyMode(user_set.isVerifyFile());
|
tik.setVerifyMode(user_set.isVerifyFile());
|
||||||
|
|
|
@ -62,40 +62,3 @@ struct sOptional
|
||||||
|
|
||||||
const byte_t kDummyRightsIdForUserTitleKey[nn::hac::nca::kRightsIdLen] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
const byte_t kDummyRightsIdForUserTitleKey[nn::hac::nca::kRightsIdLen] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||||
const byte_t kDummyRightsIdForUserBodyKey[nn::hac::nca::kRightsIdLen] = {0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
|
const byte_t kDummyRightsIdForUserBodyKey[nn::hac::nca::kRightsIdLen] = {0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
|
||||||
|
|
||||||
struct sKeyset
|
|
||||||
{
|
|
||||||
fnd::rsa::sRsa2048Key acid_sign_key;
|
|
||||||
fnd::aes::sAes128Key package1_key[kMasterKeyNum];
|
|
||||||
fnd::rsa::sRsa2048Key package2_sign_key;
|
|
||||||
fnd::aes::sAes128Key package2_key[kMasterKeyNum];
|
|
||||||
|
|
||||||
struct sNcaData
|
|
||||||
{
|
|
||||||
fnd::rsa::sRsa2048Key header_sign_key;
|
|
||||||
fnd::aes::sAesXts128Key header_key;
|
|
||||||
fnd::aes::sAes128Key key_area_key[kNcaKeakNum][kMasterKeyNum];
|
|
||||||
|
|
||||||
fnd::aes::sAes128Key manual_title_key_aesctr;
|
|
||||||
fnd::aes::sAesXts128Key manual_title_key_aesxts;
|
|
||||||
fnd::aes::sAes128Key manual_body_key_aesctr;
|
|
||||||
fnd::aes::sAesXts128Key manual_body_key_aesxts;
|
|
||||||
} nca;
|
|
||||||
|
|
||||||
struct sXciData
|
|
||||||
{
|
|
||||||
fnd::rsa::sRsa2048Key header_sign_key;
|
|
||||||
fnd::aes::sAes128Key header_key;
|
|
||||||
} xci;
|
|
||||||
|
|
||||||
struct sTicketData
|
|
||||||
{
|
|
||||||
fnd::rsa::sRsa2048Key sign_key;
|
|
||||||
fnd::aes::sAes128Key titlekey_kek[kMasterKeyNum];
|
|
||||||
} ticket;
|
|
||||||
|
|
||||||
struct sPkiData
|
|
||||||
{
|
|
||||||
fnd::rsa::sRsa4096Key root_sign_key;
|
|
||||||
} pki;
|
|
||||||
};
|
|
Loading…
Reference in a new issue