2021-10-16 08:00:17 +00:00
|
|
|
#include "EsCertProcess.h"
|
2021-10-10 09:22:55 +00:00
|
|
|
#include "PkiValidator.h"
|
|
|
|
#include "util.h"
|
|
|
|
|
2022-06-29 13:19:36 +00:00
|
|
|
#include <pietendo/hac/es/SignUtils.h>
|
2021-10-10 09:22:55 +00:00
|
|
|
|
2021-10-16 08:00:17 +00:00
|
|
|
nstool::EsCertProcess::EsCertProcess() :
|
|
|
|
mModuleName("nstool::EsCertProcess"),
|
2021-10-10 09:22:55 +00:00
|
|
|
mFile(),
|
|
|
|
mCliOutputMode(true, false, false, false),
|
|
|
|
mVerify(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-10-16 08:00:17 +00:00
|
|
|
void nstool::EsCertProcess::process()
|
2021-10-10 09:22:55 +00:00
|
|
|
{
|
|
|
|
importCerts();
|
|
|
|
|
|
|
|
if (mVerify)
|
|
|
|
validateCerts();
|
|
|
|
|
|
|
|
if (mCliOutputMode.show_basic_info)
|
|
|
|
displayCerts();
|
|
|
|
}
|
|
|
|
|
2021-10-16 08:00:17 +00:00
|
|
|
void nstool::EsCertProcess::setInputFile(const std::shared_ptr<tc::io::IStream>& file)
|
2021-10-10 09:22:55 +00:00
|
|
|
{
|
|
|
|
mFile = file;
|
|
|
|
}
|
|
|
|
|
2021-10-16 08:00:17 +00:00
|
|
|
void nstool::EsCertProcess::setKeyCfg(const KeyBag& keycfg)
|
2021-10-10 09:22:55 +00:00
|
|
|
{
|
|
|
|
mKeyCfg = keycfg;
|
|
|
|
}
|
|
|
|
|
2021-10-16 08:00:17 +00:00
|
|
|
void nstool::EsCertProcess::setCliOutputMode(CliOutputMode mode)
|
2021-10-10 09:22:55 +00:00
|
|
|
{
|
|
|
|
mCliOutputMode = mode;
|
|
|
|
}
|
|
|
|
|
2021-10-16 08:00:17 +00:00
|
|
|
void nstool::EsCertProcess::setVerifyMode(bool verify)
|
2021-10-10 09:22:55 +00:00
|
|
|
{
|
|
|
|
mVerify = verify;
|
|
|
|
}
|
|
|
|
|
2021-10-16 08:00:17 +00:00
|
|
|
void nstool::EsCertProcess::importCerts()
|
2021-10-10 09:22:55 +00:00
|
|
|
{
|
|
|
|
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());
|
|
|
|
|
2022-06-29 13:19:36 +00:00
|
|
|
pie::hac::es::SignedData<pie::hac::es::CertificateBody> cert;
|
2021-10-10 09:22:55 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-16 08:00:17 +00:00
|
|
|
void nstool::EsCertProcess::validateCerts()
|
2021-10-10 09:22:55 +00:00
|
|
|
{
|
|
|
|
PkiValidator pki;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
pki.setKeyCfg(mKeyCfg);
|
|
|
|
pki.addCertificates(mCert);
|
|
|
|
}
|
|
|
|
catch (const tc::Exception& e)
|
|
|
|
{
|
|
|
|
fmt::print("[WARNING] {}\n", e.error());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-16 08:00:17 +00:00
|
|
|
void nstool::EsCertProcess::displayCerts()
|
2021-10-10 09:22:55 +00:00
|
|
|
{
|
|
|
|
for (size_t i = 0; i < mCert.size(); i++)
|
|
|
|
{
|
|
|
|
displayCert(mCert[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-29 13:19:36 +00:00
|
|
|
void nstool::EsCertProcess::displayCert(const pie::hac::es::SignedData<pie::hac::es::CertificateBody>& cert)
|
2021-10-10 09:22:55 +00:00
|
|
|
{
|
2021-10-16 08:00:17 +00:00
|
|
|
fmt::print("[ES Certificate]\n");
|
2021-10-10 09:22:55 +00:00
|
|
|
|
|
|
|
fmt::print(" SignType {:s}", getSignTypeStr(cert.getSignature().getSignType()));
|
|
|
|
if (mCliOutputMode.show_extended_info)
|
2023-01-21 14:51:11 +00:00
|
|
|
fmt::print(" (0x{:x}) ({:s})", (uint32_t)cert.getSignature().getSignType(), getEndiannessStr(cert.getSignature().isLittleEndian()));
|
2021-10-10 09:22:55 +00:00
|
|
|
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)
|
2023-01-21 14:51:11 +00:00
|
|
|
fmt::print(" ({:d})", (uint32_t)cert.getBody().getPublicKeyType());
|
2021-10-10 09:22:55 +00:00
|
|
|
fmt::print("\n");
|
|
|
|
fmt::print(" CertID: 0x{:x}\n", cert.getBody().getCertId());
|
|
|
|
|
2022-06-29 13:19:36 +00:00
|
|
|
if (cert.getBody().getPublicKeyType() == pie::hac::es::cert::RSA4096)
|
2021-10-10 09:22:55 +00:00
|
|
|
{
|
|
|
|
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()));
|
|
|
|
}
|
|
|
|
}
|
2022-06-29 13:19:36 +00:00
|
|
|
else if (cert.getBody().getPublicKeyType() == pie::hac::es::cert::RSA2048)
|
2021-10-10 09:22:55 +00:00
|
|
|
{
|
|
|
|
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()));
|
|
|
|
}
|
|
|
|
}
|
2022-06-29 13:19:36 +00:00
|
|
|
else if (cert.getBody().getPublicKeyType() == pie::hac::es::cert::ECDSA240)
|
2021-10-10 09:22:55 +00:00
|
|
|
{
|
|
|
|
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()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-29 13:19:36 +00:00
|
|
|
std::string nstool::EsCertProcess::getSignTypeStr(pie::hac::es::sign::SignatureId type) const
|
2021-10-10 09:22:55 +00:00
|
|
|
{
|
|
|
|
std::string str;
|
|
|
|
switch (type)
|
|
|
|
{
|
2022-06-29 13:19:36 +00:00
|
|
|
case (pie::hac::es::sign::SIGN_ID_RSA4096_SHA1):
|
2021-10-10 09:22:55 +00:00
|
|
|
str = "RSA4096-SHA1";
|
|
|
|
break;
|
2022-06-29 13:19:36 +00:00
|
|
|
case (pie::hac::es::sign::SIGN_ID_RSA2048_SHA1):
|
2021-10-10 09:22:55 +00:00
|
|
|
str = "RSA2048-SHA1";
|
|
|
|
break;
|
2022-06-29 13:19:36 +00:00
|
|
|
case (pie::hac::es::sign::SIGN_ID_ECDSA240_SHA1):
|
2021-10-10 09:22:55 +00:00
|
|
|
str = "ECDSA240-SHA1";
|
|
|
|
break;
|
2022-06-29 13:19:36 +00:00
|
|
|
case (pie::hac::es::sign::SIGN_ID_RSA4096_SHA256):
|
2021-10-10 09:22:55 +00:00
|
|
|
str = "RSA4096-SHA256";
|
|
|
|
break;
|
2022-06-29 13:19:36 +00:00
|
|
|
case (pie::hac::es::sign::SIGN_ID_RSA2048_SHA256):
|
2021-10-10 09:22:55 +00:00
|
|
|
str = "RSA2048-SHA256";
|
|
|
|
break;
|
2022-06-29 13:19:36 +00:00
|
|
|
case (pie::hac::es::sign::SIGN_ID_ECDSA240_SHA256):
|
2021-10-10 09:22:55 +00:00
|
|
|
str = "ECDSA240-SHA256";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
str = "Unknown";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2021-10-16 08:00:17 +00:00
|
|
|
std::string nstool::EsCertProcess::getEndiannessStr(bool isLittleEndian) const
|
2021-10-10 09:22:55 +00:00
|
|
|
{
|
|
|
|
return isLittleEndian ? "LittleEndian" : "BigEndian";
|
|
|
|
}
|
|
|
|
|
2022-06-29 13:19:36 +00:00
|
|
|
std::string nstool::EsCertProcess::getPublicKeyTypeStr(pie::hac::es::cert::PublicKeyType type) const
|
2021-10-10 09:22:55 +00:00
|
|
|
{
|
|
|
|
std::string str;
|
|
|
|
switch (type)
|
|
|
|
{
|
2022-06-29 13:19:36 +00:00
|
|
|
case (pie::hac::es::cert::RSA4096):
|
2021-10-10 09:22:55 +00:00
|
|
|
str = "RSA4096";
|
|
|
|
break;
|
2022-06-29 13:19:36 +00:00
|
|
|
case (pie::hac::es::cert::RSA2048):
|
2021-10-10 09:22:55 +00:00
|
|
|
str = "RSA2048";
|
|
|
|
break;
|
2022-06-29 13:19:36 +00:00
|
|
|
case (pie::hac::es::cert::ECDSA240):
|
2021-10-10 09:22:55 +00:00
|
|
|
str = "ECDSA240";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
str = "Unknown";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|