mirror of
https://github.com/Dark98/threeSD.git
synced 2026-07-06 08:39:06 +00:00
Add checks for TMD and Ticket
This commit is contained in:
@@ -53,15 +53,8 @@ private:
|
|||||||
bool hash_enabled{};
|
bool hash_enabled{};
|
||||||
};
|
};
|
||||||
|
|
||||||
CIABuilder::CIABuilder(const Config& config) {
|
CIABuilder::CIABuilder(const Config& config, std::shared_ptr<TicketDB> ticket_db_)
|
||||||
if (!config.ticket_db_path.empty()) {
|
: ticket_db(std::move(ticket_db_)) {
|
||||||
ticket_db = std::make_unique<TicketDB>(config.ticket_db_path);
|
|
||||||
}
|
|
||||||
if (!ticket_db || !ticket_db->IsGood()) {
|
|
||||||
LOG_WARNING(Core, "ticket.db not present or is invalid");
|
|
||||||
ticket_db.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config.enc_title_keys_bin_path.empty()) {
|
if (!config.enc_title_keys_bin_path.empty()) {
|
||||||
enc_title_keys_bin = std::make_unique<EncTitleKeysBin>();
|
enc_title_keys_bin = std::make_unique<EncTitleKeysBin>();
|
||||||
if (!LoadTitleKeysBin(*enc_title_keys_bin, config.enc_title_keys_bin_path)) {
|
if (!LoadTitleKeysBin(*enc_title_keys_bin, config.enc_title_keys_bin_path)) {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class TicketDB;
|
|||||||
|
|
||||||
class CIABuilder {
|
class CIABuilder {
|
||||||
public:
|
public:
|
||||||
explicit CIABuilder(const Config& config);
|
explicit CIABuilder(const Config& config, std::shared_ptr<TicketDB> ticket_db);
|
||||||
~CIABuilder();
|
~CIABuilder();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -104,7 +104,7 @@ private:
|
|||||||
bool WriteTicket();
|
bool WriteTicket();
|
||||||
|
|
||||||
// Persistent state
|
// Persistent state
|
||||||
std::unique_ptr<TicketDB> ticket_db;
|
const std::shared_ptr<TicketDB> ticket_db;
|
||||||
std::unique_ptr<EncTitleKeysBin> enc_title_keys_bin;
|
std::unique_ptr<EncTitleKeysBin> enc_title_keys_bin;
|
||||||
|
|
||||||
// State of a single task
|
// State of a single task
|
||||||
|
|||||||
+10
-1
@@ -65,9 +65,18 @@ bool SDMCImporter::Init() {
|
|||||||
Certs::Load(config.certs_db_path);
|
Certs::Load(config.certs_db_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load Ticket DB
|
||||||
|
if (!config.ticket_db_path.empty()) {
|
||||||
|
ticket_db = std::make_shared<TicketDB>(config.ticket_db_path);
|
||||||
|
}
|
||||||
|
if (!ticket_db || !ticket_db->IsGood()) {
|
||||||
|
LOG_WARNING(Core, "ticket.db not present or is invalid");
|
||||||
|
ticket_db.reset();
|
||||||
|
}
|
||||||
|
|
||||||
// Create children
|
// Create children
|
||||||
sdmc_decryptor = std::make_unique<SDMCDecryptor>(config.sdmc_path);
|
sdmc_decryptor = std::make_unique<SDMCDecryptor>(config.sdmc_path);
|
||||||
cia_builder = std::make_unique<CIABuilder>(config);
|
cia_builder = std::make_unique<CIABuilder>(config, ticket_db);
|
||||||
|
|
||||||
// Load SDMC Title DB
|
// Load SDMC Title DB
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -178,6 +178,14 @@ public:
|
|||||||
bool LoadTMD(ContentType type, u64 id, TitleMetadata& out) const;
|
bool LoadTMD(ContentType type, u64 id, TitleMetadata& out) const;
|
||||||
bool LoadTMD(const ContentSpecifier& specifier, TitleMetadata& out) const;
|
bool LoadTMD(const ContentSpecifier& specifier, TitleMetadata& out) const;
|
||||||
|
|
||||||
|
std::shared_ptr<TicketDB>& GetTicketDB() {
|
||||||
|
return ticket_db;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::shared_ptr<TicketDB>& GetTicketDB() const {
|
||||||
|
return ticket_db;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool Init();
|
bool Init();
|
||||||
|
|
||||||
@@ -216,6 +224,7 @@ private:
|
|||||||
|
|
||||||
// Used for CIA building
|
// Used for CIA building
|
||||||
std::unique_ptr<CIABuilder> cia_builder;
|
std::unique_ptr<CIABuilder> cia_builder;
|
||||||
|
std::shared_ptr<TicketDB> ticket_db;
|
||||||
|
|
||||||
// The NCCH used to dump CXIs.
|
// The NCCH used to dump CXIs.
|
||||||
std::unique_ptr<NCCHContainer> dump_cxi_ncch;
|
std::unique_ptr<NCCHContainer> dump_cxi_ncch;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
#include "core/db/title_db.h"
|
||||||
#include "core/file_sys/ncch_container.h"
|
#include "core/file_sys/ncch_container.h"
|
||||||
#include "core/file_sys/title_metadata.h"
|
#include "core/file_sys/title_metadata.h"
|
||||||
#include "core/importer.h"
|
#include "core/importer.h"
|
||||||
@@ -23,16 +24,15 @@ TitleInfoDialog::TitleInfoDialog(QWidget* parent, const Core::Config& config,
|
|||||||
const double scale = qApp->desktop()->logicalDpiX() / 96.0;
|
const double scale = qApp->desktop()->logicalDpiX() / 96.0;
|
||||||
resize(static_cast<int>(width() * scale), static_cast<int>(height() * scale));
|
resize(static_cast<int>(width() * scale), static_cast<int>(height() * scale));
|
||||||
|
|
||||||
InitializeInfo(config, importer, specifier);
|
LoadInfo(config, importer, specifier);
|
||||||
InitializeLanguageComboBox();
|
|
||||||
|
|
||||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &TitleInfoDialog::accept);
|
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &TitleInfoDialog::accept);
|
||||||
}
|
}
|
||||||
|
|
||||||
TitleInfoDialog::~TitleInfoDialog() = default;
|
TitleInfoDialog::~TitleInfoDialog() = default;
|
||||||
|
|
||||||
void TitleInfoDialog::InitializeInfo(const Core::Config& config, Core::SDMCImporter& importer,
|
void TitleInfoDialog::LoadInfo(const Core::Config& config, Core::SDMCImporter& importer,
|
||||||
const Core::ContentSpecifier& specifier) {
|
const Core::ContentSpecifier& specifier) {
|
||||||
Core::TitleMetadata tmd;
|
Core::TitleMetadata tmd;
|
||||||
if (!importer.LoadTMD(specifier, tmd)) {
|
if (!importer.LoadTMD(specifier, tmd)) {
|
||||||
QMessageBox::warning(this, tr("threeSD"), tr("Could not load title information."));
|
QMessageBox::warning(this, tr("threeSD"), tr("Could not load title information."));
|
||||||
@@ -80,6 +80,27 @@ void TitleInfoDialog::InitializeInfo(const Core::Config& config, Core::SDMCImpor
|
|||||||
}
|
}
|
||||||
ui->encryptionLineEdit->setText(encryption_text);
|
ui->encryptionLineEdit->setText(encryption_text);
|
||||||
|
|
||||||
|
// Checks
|
||||||
|
const bool tmd_legit = tmd.ValidateSignature() && tmd.VerifyHashes();
|
||||||
|
if (tmd_legit) {
|
||||||
|
ui->tmdCheckLabel->setText(tr("Legit"));
|
||||||
|
} else {
|
||||||
|
ui->tmdCheckLabel->setText(tr("Illegit"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto& ticket_db = importer.GetTicketDB();
|
||||||
|
ticket_db && ticket_db->tickets.count(specifier.id)) {
|
||||||
|
|
||||||
|
const bool ticket_legit = ticket_db->tickets.at(specifier.id).ValidateSignature();
|
||||||
|
if (ticket_legit) {
|
||||||
|
ui->ticketCheckLabel->setText(tr("Legit"));
|
||||||
|
} else {
|
||||||
|
ui->ticketCheckLabel->setText(tr("Illegit"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ui->ticketCheckLabel->setText(tr("Missing"));
|
||||||
|
}
|
||||||
|
|
||||||
// Load SMDH
|
// Load SMDH
|
||||||
std::vector<u8> smdh_buffer;
|
std::vector<u8> smdh_buffer;
|
||||||
if (!ncch.LoadSectionExeFS("icon", smdh_buffer) || smdh_buffer.size() != sizeof(Core::SMDH) ||
|
if (!ncch.LoadSectionExeFS("icon", smdh_buffer) || smdh_buffer.size() != sizeof(Core::SMDH) ||
|
||||||
@@ -98,6 +119,8 @@ void TitleInfoDialog::InitializeInfo(const Core::Config& config, Core::SDMCImpor
|
|||||||
ui->iconSmallLabel->setPixmap(
|
ui->iconSmallLabel->setPixmap(
|
||||||
QPixmap::fromImage(QImage(reinterpret_cast<const uchar*>(smdh.GetIcon(false).data()), 24,
|
QPixmap::fromImage(QImage(reinterpret_cast<const uchar*>(smdh.GetIcon(false).data()), 24,
|
||||||
24, QImage::Format::Format_RGB16)));
|
24, QImage::Format::Format_RGB16)));
|
||||||
|
// Load names
|
||||||
|
InitializeLanguageComboBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TitleInfoDialog::InitializeLanguageComboBox() {
|
void TitleInfoDialog::InitializeLanguageComboBox() {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace Core {
|
|||||||
class Config;
|
class Config;
|
||||||
class ContentSpecifier;
|
class ContentSpecifier;
|
||||||
class SDMCImporter;
|
class SDMCImporter;
|
||||||
|
class TitleMetadata;
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
@@ -25,8 +26,8 @@ public:
|
|||||||
~TitleInfoDialog();
|
~TitleInfoDialog();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitializeInfo(const Core::Config& config, Core::SDMCImporter& importer,
|
void LoadInfo(const Core::Config& config, Core::SDMCImporter& importer,
|
||||||
const Core::ContentSpecifier& specifier);
|
const Core::ContentSpecifier& specifier);
|
||||||
void InitializeLanguageComboBox();
|
void InitializeLanguageComboBox();
|
||||||
void UpdateNames();
|
void UpdateNames();
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,11 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLineEdit" name="versionLineEdit"/>
|
<widget class="QLineEdit" name="versionLineEdit">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="2" rowspan="2">
|
<item row="0" column="2" rowspan="2">
|
||||||
<widget class="QLabel" name="iconLargeLabel">
|
<widget class="QLabel" name="iconLargeLabel">
|
||||||
@@ -58,7 +62,11 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QLineEdit" name="encryptionLineEdit"/>
|
<widget class="QLineEdit" name="encryptionLineEdit">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel">
|
<widget class="QLabel">
|
||||||
@@ -68,7 +76,11 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1" colspan="3">
|
<item row="2" column="1" colspan="3">
|
||||||
<widget class="QLineEdit" name="titleIDLineEdit"/>
|
<widget class="QLineEdit" name="titleIDLineEdit">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
@@ -87,7 +99,11 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLineEdit" name="shortTitleLineEdit"/>
|
<widget class="QLineEdit" name="shortTitleLineEdit">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="2">
|
<item row="0" column="2">
|
||||||
<widget class="QComboBox" name="languageComboBox"/>
|
<widget class="QComboBox" name="languageComboBox"/>
|
||||||
@@ -100,7 +116,11 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1" colspan="2">
|
<item row="1" column="1" colspan="2">
|
||||||
<widget class="QLineEdit" name="longTitleLineEdit"/>
|
<widget class="QLineEdit" name="longTitleLineEdit">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel">
|
<widget class="QLabel">
|
||||||
@@ -110,7 +130,11 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1" colspan="2">
|
<item row="2" column="1" colspan="2">
|
||||||
<widget class="QLineEdit" name="publisherLineEdit"/>
|
<widget class="QLineEdit" name="publisherLineEdit">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|||||||
Reference in New Issue
Block a user