From 2d5f95fbcf0e7fcf08dff89f2f0c4634e933da19 Mon Sep 17 00:00:00 2001 From: jakcron Date: Sun, 10 Oct 2021 17:22:55 +0800 Subject: [PATCH] Port PkiCertProcess to libtoolchain. --- build/visualstudio/nstool/nstool.vcxproj | 1 + .../nstool/nstool.vcxproj.filters | 3 + src/PkiCertProcess.cpp | 228 ++++++++++++++++++ src/PkiCertProcess.h | 10 +- src/main.cpp | 4 +- src/not_ported/PkiCertProcess.cpp | 193 --------------- 6 files changed, 238 insertions(+), 201 deletions(-) create mode 100644 src/PkiCertProcess.cpp delete mode 100644 src/not_ported/PkiCertProcess.cpp diff --git a/build/visualstudio/nstool/nstool.vcxproj b/build/visualstudio/nstool/nstool.vcxproj index 7eeb132..f452499 100644 --- a/build/visualstudio/nstool/nstool.vcxproj +++ b/build/visualstudio/nstool/nstool.vcxproj @@ -189,6 +189,7 @@ + diff --git a/build/visualstudio/nstool/nstool.vcxproj.filters b/build/visualstudio/nstool/nstool.vcxproj.filters index 7358652..69e6c9f 100644 --- a/build/visualstudio/nstool/nstool.vcxproj.filters +++ b/build/visualstudio/nstool/nstool.vcxproj.filters @@ -140,5 +140,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/src/PkiCertProcess.cpp b/src/PkiCertProcess.cpp new file mode 100644 index 0000000..6ddb2b1 --- /dev/null +++ b/src/PkiCertProcess.cpp @@ -0,0 +1,228 @@ +#include "PkiCertProcess.h" +#include "PkiValidator.h" +#include "util.h" + +#include + +nstool::PkiCertProcess::PkiCertProcess() : + mModuleName("nstool::PkiCertProcess"), + mFile(), + mCliOutputMode(true, false, false, false), + mVerify(false) +{ +} + +void nstool::PkiCertProcess::process() +{ + importCerts(); + + if (mVerify) + validateCerts(); + + if (mCliOutputMode.show_basic_info) + displayCerts(); +} + +void nstool::PkiCertProcess::setInputFile(const std::shared_ptr& file) +{ + mFile = file; +} + +void nstool::PkiCertProcess::setKeyCfg(const KeyBag& keycfg) +{ + mKeyCfg = keycfg; +} + +void nstool::PkiCertProcess::setCliOutputMode(CliOutputMode mode) +{ + mCliOutputMode = mode; +} + +void nstool::PkiCertProcess::setVerifyMode(bool verify) +{ + mVerify = verify; +} + +void nstool::PkiCertProcess::importCerts() +{ + if (mFile == nullptr) + { + throw tc::Exception(mModuleName, "No file reader set."); + } + if (mFile->canRead() == false || mFile->canSeek() == false) + { + throw tc::NotSupportedException(mModuleName, "Input stream requires read/seek permissions."); + } + + // check if file_size is greater than 20MB, don't import. + size_t file_size = tc::io::IOUtil::castInt64ToSize(mFile->length()); + if (file_size > (0x100000 * 20)) + { + throw tc::Exception(mModuleName, "File too large."); + } + + // import certs + tc::ByteData scratch = tc::ByteData(file_size); + mFile->seek(0, tc::io::SeekOrigin::Begin); + mFile->read(scratch.data(), scratch.size()); + + nn::pki::SignedData cert; + for (size_t f_pos = 0; f_pos < scratch.size(); f_pos += cert.getBytes().size()) + { + cert.fromBytes(scratch.data() + f_pos, scratch.size() - f_pos); + mCert.push_back(cert); + } +} + +void nstool::PkiCertProcess::validateCerts() +{ + PkiValidator pki; + + try + { + pki.setKeyCfg(mKeyCfg); + pki.addCertificates(mCert); + } + catch (const tc::Exception& e) + { + fmt::print("[WARNING] {}\n", e.error()); + return; + } +} + +void nstool::PkiCertProcess::displayCerts() +{ + for (size_t i = 0; i < mCert.size(); i++) + { + displayCert(mCert[i]); + } +} + +void nstool::PkiCertProcess::displayCert(const nn::pki::SignedData& cert) +{ + fmt::print("[NNPKI Certificate]\n"); + + fmt::print(" SignType {:s}", getSignTypeStr(cert.getSignature().getSignType())); + if (mCliOutputMode.show_extended_info) + fmt::print(" (0x{:x}) ({:s})", cert.getSignature().getSignType(), getEndiannessStr(cert.getSignature().isLittleEndian())); + fmt::print("\n"); + + fmt::print(" Issuer: {:s}\n", cert.getBody().getIssuer()); + fmt::print(" Subject: {:s}\n", cert.getBody().getSubject()); + fmt::print(" PublicKeyType: {:s}", getPublicKeyTypeStr(cert.getBody().getPublicKeyType())); + if (mCliOutputMode.show_extended_info) + fmt::print(" ({:d})", cert.getBody().getPublicKeyType()); + fmt::print("\n"); + fmt::print(" CertID: 0x{:x}\n", cert.getBody().getCertId()); + + if (cert.getBody().getPublicKeyType() == nn::pki::cert::RSA4096) + { + fmt::print(" PublicKey:\n"); + if (mCliOutputMode.show_extended_info) + { + fmt::print(" Modulus:\n"); + fmt::print(" {:s}", tc::cli::FormatUtil::formatBytesAsStringWithLineLimit(cert.getBody().getRsa4096PublicKey().n.data(), cert.getBody().getRsa4096PublicKey().n.size(), true, "", 0x10, 6, false)); + fmt::print(" Public Exponent:\n"); + fmt::print(" {:s}", tc::cli::FormatUtil::formatBytesAsStringWithLineLimit(cert.getBody().getRsa4096PublicKey().e.data(), cert.getBody().getRsa4096PublicKey().e.size(), true, "", 0x10, 6, false)); + } + else + { + fmt::print(" Modulus:\n"); + fmt::print(" {:s}\n", getTruncatedBytesString(cert.getBody().getRsa4096PublicKey().n.data(), cert.getBody().getRsa4096PublicKey().n.size())); + fmt::print(" Public Exponent:\n"); + fmt::print(" {:s}\n", getTruncatedBytesString(cert.getBody().getRsa4096PublicKey().e.data(), cert.getBody().getRsa4096PublicKey().e.size())); + } + } + else if (cert.getBody().getPublicKeyType() == nn::pki::cert::RSA2048) + { + fmt::print(" PublicKey:\n"); + if (mCliOutputMode.show_extended_info) + { + fmt::print(" Modulus:\n"); + fmt::print(" {:s}", tc::cli::FormatUtil::formatBytesAsStringWithLineLimit(cert.getBody().getRsa2048PublicKey().n.data(), cert.getBody().getRsa2048PublicKey().n.size(), true, "", 0x10, 6, false)); + fmt::print(" Public Exponent:\n"); + fmt::print(" {:s}", tc::cli::FormatUtil::formatBytesAsStringWithLineLimit(cert.getBody().getRsa2048PublicKey().e.data(), cert.getBody().getRsa2048PublicKey().e.size(), true, "", 0x10, 6, false)); + } + else + { + fmt::print(" Modulus:\n"); + fmt::print(" {:s}\n", getTruncatedBytesString(cert.getBody().getRsa2048PublicKey().n.data(), cert.getBody().getRsa2048PublicKey().n.size())); + fmt::print(" Public Exponent:\n"); + fmt::print(" {:s}\n", getTruncatedBytesString(cert.getBody().getRsa2048PublicKey().e.data(), cert.getBody().getRsa2048PublicKey().e.size())); + } + } + else if (cert.getBody().getPublicKeyType() == nn::pki::cert::ECDSA240) + { + fmt::print(" PublicKey:\n"); + if (mCliOutputMode.show_extended_info) + { + fmt::print(" Modulus:\n"); + fmt::print(" {:s}", tc::cli::FormatUtil::formatBytesAsStringWithLineLimit(cert.getBody().getEcdsa240PublicKey().r.data(), cert.getBody().getEcdsa240PublicKey().r.size(), true, "", 0x10, 6, false)); + fmt::print(" Public Exponent:\n"); + fmt::print(" {:s}", tc::cli::FormatUtil::formatBytesAsStringWithLineLimit(cert.getBody().getEcdsa240PublicKey().s.data(), cert.getBody().getEcdsa240PublicKey().s.size(), true, "", 0x10, 6, false)); + } + else + { + fmt::print(" Modulus:\n"); + fmt::print(" {:s}\n", getTruncatedBytesString(cert.getBody().getEcdsa240PublicKey().r.data(), cert.getBody().getEcdsa240PublicKey().r.size())); + fmt::print(" Public Exponent:\n"); + fmt::print(" {:s}\n", getTruncatedBytesString(cert.getBody().getEcdsa240PublicKey().s.data(), cert.getBody().getEcdsa240PublicKey().s.size())); + } + } +} + +std::string nstool::PkiCertProcess::getSignTypeStr(nn::pki::sign::SignatureId type) const +{ + std::string str; + switch (type) + { + case (nn::pki::sign::SIGN_ID_RSA4096_SHA1): + str = "RSA4096-SHA1"; + break; + case (nn::pki::sign::SIGN_ID_RSA2048_SHA1): + str = "RSA2048-SHA1"; + break; + case (nn::pki::sign::SIGN_ID_ECDSA240_SHA1): + str = "ECDSA240-SHA1"; + break; + case (nn::pki::sign::SIGN_ID_RSA4096_SHA256): + str = "RSA4096-SHA256"; + break; + case (nn::pki::sign::SIGN_ID_RSA2048_SHA256): + str = "RSA2048-SHA256"; + break; + case (nn::pki::sign::SIGN_ID_ECDSA240_SHA256): + str = "ECDSA240-SHA256"; + break; + default: + str = "Unknown"; + break; + } + return str; +} + +std::string nstool::PkiCertProcess::getEndiannessStr(bool isLittleEndian) const +{ + return isLittleEndian ? "LittleEndian" : "BigEndian"; +} + +std::string nstool::PkiCertProcess::getPublicKeyTypeStr(nn::pki::cert::PublicKeyType type) const +{ + std::string str; + switch (type) + { + case (nn::pki::cert::RSA4096): + str = "RSA4096"; + break; + case (nn::pki::cert::RSA2048): + str = "RSA2048"; + break; + case (nn::pki::cert::ECDSA240): + str = "ECDSA240"; + break; + default: + str = "Unknown"; + break; + } + return str; +} \ No newline at end of file diff --git a/src/PkiCertProcess.h b/src/PkiCertProcess.h index b5794c5..2c4c5cf 100644 --- a/src/PkiCertProcess.h +++ b/src/PkiCertProcess.h @@ -20,8 +20,7 @@ public: void setVerifyMode(bool verify); private: - const std::string kModuleName = "PkiCertProcess"; - static const size_t kSmallHexDumpLen = 0x10; + std::string mModuleName; std::shared_ptr mFile; KeyBag mKeyCfg; @@ -35,10 +34,9 @@ private: void displayCerts(); void displayCert(const nn::pki::SignedData& cert); - size_t getHexDumpLen(size_t max_size) const; - const char* getSignTypeStr(nn::pki::sign::SignatureId type) const; - const char* getEndiannessStr(bool isLittleEndian) const; - const char* getPublicKeyTypeStr(nn::pki::cert::PublicKeyType type) const; + std::string getSignTypeStr(nn::pki::sign::SignatureId type) const; + std::string getEndiannessStr(bool isLittleEndian) const; + std::string getPublicKeyTypeStr(nn::pki::cert::PublicKeyType type) const; }; } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 8036edd..2eb2230 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,7 +14,7 @@ #include "NacpProcess.h" //#include "IniProcess.h" //#include "KipProcess.h" -//#include "PkiCertProcess.h" +#include "PkiCertProcess.h" #include "EsTikProcess.h" #include "AssetProcess.h" @@ -188,6 +188,7 @@ int umain(const std::vector& args, const std::vector& obj.process(); } + */ else if (set.infile.filetype == nstool::Settings::FILE_TYPE_PKI_CERT) { nstool::PkiCertProcess obj; @@ -199,7 +200,6 @@ int umain(const std::vector& args, const std::vector& obj.process(); } - */ else if (set.infile.filetype == nstool::Settings::FILE_TYPE_ES_TIK) { nstool::EsTikProcess obj; diff --git a/src/not_ported/PkiCertProcess.cpp b/src/not_ported/PkiCertProcess.cpp deleted file mode 100644 index 45ce6b7..0000000 --- a/src/not_ported/PkiCertProcess.cpp +++ /dev/null @@ -1,193 +0,0 @@ -#include -#include -#include -#include -#include -#include "PkiCertProcess.h" -#include "PkiValidator.h" - -nstool::PkiCertProcess::PkiCertProcess() : - mFile(), - mCliOutputMode(true, false, false, false), - mVerify(false) -{ -} - -void nstool::PkiCertProcess::process() -{ - importCerts(); - - if (mVerify) - validateCerts(); - - if (mCliOutputMode.show_basic_info) - displayCerts(); -} - -void nstool::PkiCertProcess::setInputFile(const std::shared_ptr& file) -{ - mFile = file; -} - -void nstool::PkiCertProcess::setKeyCfg(const KeyBag& keycfg) -{ - mKeyCfg = keycfg; -} - -void nstool::PkiCertProcess::setCliOutputMode(CliOutputMode mode) -{ - mCliOutputMode = mode; -} - -void nstool::PkiCertProcess::setVerifyMode(bool verify) -{ - mVerify = verify; -} - -void nstool::PkiCertProcess::importCerts() -{ - tc::ByteData scratch; - - if (*mFile == nullptr) - { - throw tc::Exception(kModuleName, "No file reader set."); - } - - scratch.alloc((*mFile)->size()); - (*mFile)->read(scratch.data(), 0, scratch.size()); - - nn::pki::SignedData cert; - for (size_t f_pos = 0; f_pos < scratch.size(); f_pos += cert.getBytes().size()) - { - cert.fromBytes(scratch.data() + f_pos, scratch.size() - f_pos); - mCert.push_back(cert); - } -} - -void nstool::PkiCertProcess::validateCerts() -{ - PkiValidator pki; - - try - { - pki.setKeyCfg(mKeyCfg); - pki.addCertificates(mCert); - } - catch (const tc::Exception& e) - { - std::cout << "[WARNING] " << e.error() << std::endl; - return; - } -} - -void nstool::PkiCertProcess::displayCerts() -{ - for (size_t i = 0; i < mCert.size(); i++) - { - displayCert(mCert[i]); - } -} - -void nstool::PkiCertProcess::displayCert(const nn::pki::SignedData& cert) -{ - std::cout << "[NNPKI Certificate]" << std::endl; - - std::cout << " SignType " << getSignTypeStr(cert.getSignature().getSignType()); - if (mCliOutputMode.show_extended_info) - std::cout << " (0x" << std::hex << cert.getSignature().getSignType() << ") (" << getEndiannessStr(cert.getSignature().isLittleEndian()) << ")"; - std::cout << std::endl; - - std::cout << " Issuer: " << cert.getBody().getIssuer() << std::endl; - std::cout << " Subject: " << cert.getBody().getSubject() << std::endl; - std::cout << " PublicKeyType: " << getPublicKeyTypeStr(cert.getBody().getPublicKeyType()); - if (mCliOutputMode.show_extended_info) - std::cout << " (" << std::dec << cert.getBody().getPublicKeyType() << ")"; - std::cout << std::endl; - std::cout << " CertID: 0x" << std::hex << cert.getBody().getCertId() << std::endl; - - if (cert.getBody().getPublicKeyType() == nn::pki::cert::RSA4096) - { - std::cout << " PublicKey:" << std::endl; - std::cout << " Modulus:" << std::endl; - fnd::SimpleTextOutput::hexDump(cert.getBody().getRsa4098PublicKey().modulus, getHexDumpLen(fnd::rsa::kRsa4096Size), 0x10, 6); - std::cout << " Public Exponent:" << std::endl; - fnd::SimpleTextOutput::hexDump(cert.getBody().getRsa4098PublicKey().public_exponent, fnd::rsa::kRsaPublicExponentSize, 0x10, 6); - } - else if (cert.getBody().getPublicKeyType() == nn::pki::cert::RSA2048) - { - std::cout << " PublicKey:" << std::endl; - std::cout << " Modulus:" << std::endl; - fnd::SimpleTextOutput::hexDump(cert.getBody().getRsa2048PublicKey().modulus, getHexDumpLen(fnd::rsa::kRsa2048Size), 0x10, 6); - std::cout << " Public Exponent:" << std::endl; - fnd::SimpleTextOutput::hexDump(cert.getBody().getRsa2048PublicKey().public_exponent, fnd::rsa::kRsaPublicExponentSize, 0x10, 6); - } - else if (cert.getBody().getPublicKeyType() == nn::pki::cert::ECDSA240) - { - std::cout << " PublicKey:" << std::endl; - std::cout << " R:" << std::endl; - fnd::SimpleTextOutput::hexDump(cert.getBody().getEcdsa240PublicKey().r, getHexDumpLen(fnd::ecdsa::kEcdsa240Size), 0x10, 6); - std::cout << " S:" << std::endl; - fnd::SimpleTextOutput::hexDump(cert.getBody().getEcdsa240PublicKey().s, getHexDumpLen(fnd::ecdsa::kEcdsa240Size), 0x10, 6); - } -} - -size_t nstool::PkiCertProcess::getHexDumpLen(size_t max_size) const -{ - return mCliOutputMode.show_extended_info ? max_size : kSmallHexDumpLen; -} - -const char* nstool::PkiCertProcess::getSignTypeStr(nn::pki::sign::SignatureId type) const -{ - const char* str; - switch (type) - { - case (nn::pki::sign::SIGN_ID_RSA4096_SHA1): - str = "RSA4096-SHA1"; - break; - case (nn::pki::sign::SIGN_ID_RSA2048_SHA1): - str = "RSA2048-SHA1"; - break; - case (nn::pki::sign::SIGN_ID_ECDSA240_SHA1): - str = "ECDSA240-SHA1"; - break; - case (nn::pki::sign::SIGN_ID_RSA4096_SHA256): - str = "RSA4096-SHA256"; - break; - case (nn::pki::sign::SIGN_ID_RSA2048_SHA256): - str = "RSA2048-SHA256"; - break; - case (nn::pki::sign::SIGN_ID_ECDSA240_SHA256): - str = "ECDSA240-SHA256"; - break; - default: - str = "Unknown"; - break; - } - return str; -} - -const char* nstool::PkiCertProcess::getEndiannessStr(bool isLittleEndian) const -{ - return isLittleEndian ? "LittleEndian" : "BigEndian"; -} - -const char* nstool::PkiCertProcess::getPublicKeyTypeStr(nn::pki::cert::PublicKeyType type) const -{ - const char* str; - switch (type) - { - case (nn::pki::cert::RSA4096): - str = "RSA4096"; - break; - case (nn::pki::cert::RSA2048): - str = "RSA2048"; - break; - case (nn::pki::cert::ECDSA240): - str = "ECDSA240"; - break; - default: - str = "Unknown"; - break; - } - return str; -} \ No newline at end of file