[nstool] Root issuer validation, via key provided in key file.

This commit is contained in:
jakcron 2018-07-30 04:21:19 +08:00
parent 0aebf43f4b
commit a569ecc29d
4 changed files with 47 additions and 30 deletions

View file

@ -25,6 +25,10 @@ package2_sign_key_private : RSA2048 Private Exponent (0x100 bytes)
; Ticket Keys ; Ticket Keys
ticket_commonkey_## : AES128 Key (0x10 bytes) ticket_commonkey_## : AES128 Key (0x10 bytes)
; PKI Root Signing Key
pki_root_sign_key_modulus : RSA4096 Modulus (0x200 bytes)
pki_root_sign_key_private : RSA4096 Private Exponent (0x200 bytes)
; NCA Keys ; NCA Keys
nca_header_key : AES128-XTS Key (0x20 bytes) nca_header_key : AES128-XTS Key (0x20 bytes)
nca_header_sign_key_modulus : RSA2048 Modulus (0x100 bytes) nca_header_sign_key_modulus : RSA2048 Modulus (0x100 bytes)

View file

@ -93,12 +93,6 @@ void EsCertProcess::validateCert(const es::SignedData<es::CertificateBody>& cert
try try
{ {
// special case if signed by Root
if (cert.getBody().getIssuer() == es::sign::kRootIssuerStr)
{
throw fnd::Exception(kModuleName, "Signed by Root");
}
// get cert hash // get cert hash
switch (cert_hash_algo) switch (cert_hash_algo)
{ {
@ -112,28 +106,40 @@ void EsCertProcess::validateCert(const es::SignedData<es::CertificateBody>& cert
throw fnd::Exception(kModuleName, "Unrecognised hash type"); throw fnd::Exception(kModuleName, "Unrecognised hash type");
} }
// try to find issuer cert
const es::CertificateBody& issuer = getIssuerCert(cert.getBody().getIssuer()).getBody();
es::cert::PublicKeyType issuer_pubk_type = issuer.getPublicKeyType();
// validate signature // validate signature
int sig_validate_res = -1; int sig_validate_res = -1;
if (issuer_pubk_type == es::cert::RSA4096 && cert_sign_algo == es::sign::SIGN_ALGO_RSA4096) // special case if signed by Root
if (cert.getBody().getIssuer() == es::sign::kRootIssuerStr)
{ {
sig_validate_res = crypto::rsa::pkcs::rsaVerify(issuer.getRsa4098PublicKey(), getCryptoHashAlgoFromEsSignHashAlgo(cert_hash_algo), cert_hash, cert.getSignature().getSignature().data()); if (cert_sign_algo != es::sign::SIGN_ALGO_RSA4096)
} {
else if (issuer_pubk_type == es::cert::RSA2048 && cert_sign_algo == es::sign::SIGN_ALGO_RSA2048) throw fnd::Exception(kModuleName, "Issued by Root, but does not have a RSA4096 signature");
{ }
sig_validate_res = crypto::rsa::pkcs::rsaVerify(issuer.getRsa2048PublicKey(), getCryptoHashAlgoFromEsSignHashAlgo(cert_hash_algo), cert_hash, cert.getSignature().getSignature().data()); sig_validate_res = crypto::rsa::pkcs::rsaVerify(mKeyset->pki_root_sign_key, getCryptoHashAlgoFromEsSignHashAlgo(cert_hash_algo), cert_hash, cert.getSignature().getSignature().data());
}
else if (issuer_pubk_type == es::cert::ECDSA240 && cert_sign_algo == es::sign::SIGN_ALGO_ECDSA240)
{
throw fnd::Exception(kModuleName, "ECDSA signatures are not supported");
} }
else else
{ {
throw fnd::Exception(kModuleName, "Mismatch between issuer public key and signature type"); // try to find issuer cert
const es::CertificateBody& issuer = getIssuerCert(cert.getBody().getIssuer()).getBody();
es::cert::PublicKeyType issuer_pubk_type = issuer.getPublicKeyType();
if (issuer_pubk_type == es::cert::RSA4096 && cert_sign_algo == es::sign::SIGN_ALGO_RSA4096)
{
sig_validate_res = crypto::rsa::pkcs::rsaVerify(issuer.getRsa4098PublicKey(), getCryptoHashAlgoFromEsSignHashAlgo(cert_hash_algo), cert_hash, cert.getSignature().getSignature().data());
}
else if (issuer_pubk_type == es::cert::RSA2048 && cert_sign_algo == es::sign::SIGN_ALGO_RSA2048)
{
sig_validate_res = crypto::rsa::pkcs::rsaVerify(issuer.getRsa2048PublicKey(), getCryptoHashAlgoFromEsSignHashAlgo(cert_hash_algo), cert_hash, cert.getSignature().getSignature().data());
}
else if (issuer_pubk_type == es::cert::ECDSA240 && cert_sign_algo == es::sign::SIGN_ALGO_ECDSA240)
{
throw fnd::Exception(kModuleName, "ECDSA signatures are not supported");
}
else
{
throw fnd::Exception(kModuleName, "Mismatch between issuer public key and signature type");
}
} }
if (sig_validate_res != 0) if (sig_validate_res != 0)

View file

@ -423,6 +423,7 @@ void UserSettings::populateKeyset(sCmdArgs& args)
const std::string kKekGenSource = "aes_kek_generation"; const std::string kKekGenSource = "aes_kek_generation";
const std::string kKeyGenSource = "aes_key_generation"; const std::string kKeyGenSource = "aes_key_generation";
const std::string kAcidBase = "acid"; const std::string kAcidBase = "acid";
const std::string kPkiRootBase = "pki_root";
const std::string kTicketCommonKeyBase[2] = { "titlekek", "ticket_commonkey" }; const std::string kTicketCommonKeyBase[2] = { "titlekek", "ticket_commonkey" };
const std::string kNcaBodyBase[2] = {"key_area_key", "nca_body_keak"}; const std::string kNcaBodyBase[2] = {"key_area_key", "nca_body_keak"};
const std::string kNcaBodyKeakIndexName[3] = {"application", "ocean", "system"}; const std::string kNcaBodyKeakIndexName[3] = {"application", "ocean", "system"};
@ -492,17 +493,21 @@ void UserSettings::populateKeyset(sCmdArgs& args)
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kXciHeaderBase, kKeyStr), mKeyset.xci.header_key.key, 0x10); _SAVE_KEYDATA(_CONCAT_2_STRINGS(kXciHeaderBase, kKeyStr), mKeyset.xci.header_key.key, 0x10);
// store rsa keys // store rsa keys
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kNcaHeaderBase[1], kRsaKeySuffix[0]), mKeyset.nca.header_sign_key.priv_exponent, 0x100); _SAVE_KEYDATA(_CONCAT_2_STRINGS(kNcaHeaderBase[1], kRsaKeySuffix[0]), mKeyset.nca.header_sign_key.priv_exponent, crypto::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kNcaHeaderBase[1], kRsaKeySuffix[1]), mKeyset.nca.header_sign_key.modulus, 0x100); _SAVE_KEYDATA(_CONCAT_2_STRINGS(kNcaHeaderBase[1], kRsaKeySuffix[1]), mKeyset.nca.header_sign_key.modulus, crypto::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kXciHeaderBase, kRsaKeySuffix[0]), mKeyset.xci.header_sign_key.priv_exponent, 0x100); _SAVE_KEYDATA(_CONCAT_2_STRINGS(kXciHeaderBase, kRsaKeySuffix[0]), mKeyset.xci.header_sign_key.priv_exponent, crypto::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kXciHeaderBase, kRsaKeySuffix[1]), mKeyset.xci.header_sign_key.modulus, 0x100); _SAVE_KEYDATA(_CONCAT_2_STRINGS(kXciHeaderBase, kRsaKeySuffix[1]), mKeyset.xci.header_sign_key.modulus, crypto::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kAcidBase, kRsaKeySuffix[0]), mKeyset.acid_sign_key.priv_exponent, 0x100); _SAVE_KEYDATA(_CONCAT_2_STRINGS(kAcidBase, kRsaKeySuffix[0]), mKeyset.acid_sign_key.priv_exponent, crypto::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kAcidBase, kRsaKeySuffix[1]), mKeyset.acid_sign_key.modulus, 0x100); _SAVE_KEYDATA(_CONCAT_2_STRINGS(kAcidBase, kRsaKeySuffix[1]), mKeyset.acid_sign_key.modulus, crypto::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kPackage2Base, kRsaKeySuffix[0]), mKeyset.package2_sign_key.priv_exponent, crypto::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kPackage2Base, kRsaKeySuffix[1]), mKeyset.package2_sign_key.modulus, crypto::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kPkiRootBase, kRsaKeySuffix[0]), mKeyset.pki_root_sign_key.priv_exponent, crypto::rsa::kRsa4096Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kPkiRootBase, kRsaKeySuffix[1]), mKeyset.pki_root_sign_key.modulus, crypto::rsa::kRsa4096Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kPackage2Base, kRsaKeySuffix[0]), mKeyset.package2_sign_key.priv_exponent, 0x100);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kPackage2Base, kRsaKeySuffix[1]), mKeyset.package2_sign_key.modulus, 0x100);
// save keydata from input args // save keydata from input args
if (args.nca_bodykey.isSet) if (args.nca_bodykey.isSet)

View file

@ -65,6 +65,8 @@ struct sKeyset
{ {
crypto::rsa::sRsa2048Key acid_sign_key; crypto::rsa::sRsa2048Key acid_sign_key;
crypto::rsa::sRsa4096Key pki_root_sign_key;
crypto::aes::sAes128Key package1_key[kMasterKeyNum]; crypto::aes::sAes128Key package1_key[kMasterKeyNum];
crypto::rsa::sRsa2048Key package2_sign_key; crypto::rsa::sRsa2048Key package2_sign_key;
crypto::aes::sAes128Key package2_key[kMasterKeyNum]; crypto::aes::sAes128Key package2_key[kMasterKeyNum];
@ -86,7 +88,7 @@ struct sKeyset
crypto::rsa::sRsa2048Key header_sign_key; crypto::rsa::sRsa2048Key header_sign_key;
crypto::aes::sAes128Key header_key; crypto::aes::sAes128Key header_key;
} xci; } xci;
struct sTicketData struct sTicketData
{ {
crypto::rsa::sRsa2048Key sign_key; crypto::rsa::sRsa2048Key sign_key;