VolumeVerifier: Split TMD error from ticket error for WADs

When I first made VolumeVerifier, I figured that the distinction
between an unsigned ticket and an unsigned TMD was a technical
detail that users would have no reason to care about. However,
while this might be true for discs, it isn't equally true for
WADs, due to the widespread practice of fakesigning tickets to
set the console ID to 0. This practice does not require
fakesigning the TMD (though apparently people do it anyway,
at least sometimes...), and the presence of a correctly signed
TMD is a useful indicator that the contents have not been
tampered with, even if the ticket isn't correctly signed.
This commit is contained in:
JosJuice 2020-08-08 19:38:50 +02:00
parent 3201944208
commit 7ef0bc0359
2 changed files with 42 additions and 26 deletions

View File

@ -391,8 +391,6 @@ void VolumeVerifier::Start()
(m_volume.GetVolumeType() == Platform::WiiDisc && !m_volume.IsEncryptedAndHashed()) ||
IsDebugSigned();
if (m_volume.GetVolumeType() == Platform::WiiWAD)
CheckCorrectlySigned(PARTITION_NONE, Common::GetStringT("This title is not correctly signed."));
CheckDiscSize(CheckPartitions());
CheckMisc();
@ -525,10 +523,24 @@ bool VolumeVerifier::CheckPartition(const Partition& partition)
if (!m_is_datel)
{
CheckCorrectlySigned(
partition,
StringFromFormat(Common::GetStringT("The %s partition is not correctly signed.").c_str(),
name.c_str()));
IOS::HLE::Kernel ios;
const auto es = ios.GetES();
const std::vector<u8>& cert_chain = m_volume.GetCertificateChain(partition);
if (IOS::HLE::IPC_SUCCESS !=
es->VerifyContainer(IOS::HLE::Device::ES::VerifyContainerType::Ticket,
IOS::HLE::Device::ES::VerifyMode::DoNotUpdateCertStore,
m_volume.GetTicket(partition), cert_chain) ||
IOS::HLE::IPC_SUCCESS !=
es->VerifyContainer(IOS::HLE::Device::ES::VerifyContainerType::TMD,
IOS::HLE::Device::ES::VerifyMode::DoNotUpdateCertStore,
m_volume.GetTMD(partition), cert_chain))
{
AddProblem(
Severity::Low,
StringFromFormat(Common::GetStringT("The %s partition is not correctly signed.").c_str(),
name.c_str()));
}
}
if (m_volume.SupportsIntegrityCheck() && !m_volume.CheckH3TableIntegrity(partition))
@ -664,25 +676,6 @@ std::string VolumeVerifier::GetPartitionName(std::optional<u32> type) const
return name;
}
void VolumeVerifier::CheckCorrectlySigned(const Partition& partition, std::string error_text)
{
IOS::HLE::Kernel ios;
const auto es = ios.GetES();
const std::vector<u8> cert_chain = m_volume.GetCertificateChain(partition);
if (IOS::HLE::IPC_SUCCESS !=
es->VerifyContainer(IOS::HLE::Device::ES::VerifyContainerType::Ticket,
IOS::HLE::Device::ES::VerifyMode::DoNotUpdateCertStore,
m_volume.GetTicket(partition), cert_chain) ||
IOS::HLE::IPC_SUCCESS !=
es->VerifyContainer(IOS::HLE::Device::ES::VerifyContainerType::TMD,
IOS::HLE::Device::ES::VerifyMode::DoNotUpdateCertStore,
m_volume.GetTMD(partition), cert_chain))
{
AddProblem(Severity::Low, std::move(error_text));
}
}
bool VolumeVerifier::IsDebugSigned() const
{
const IOS::ES::TicketReader& ticket = m_volume.GetTicket(m_volume.GetGamePartition());
@ -988,6 +981,30 @@ void VolumeVerifier::CheckMisc()
}
}
if (m_volume.GetVolumeType() == Platform::WiiWAD)
{
IOS::HLE::Kernel ios;
const auto es = ios.GetES();
const std::vector<u8>& cert_chain = m_volume.GetCertificateChain(PARTITION_NONE);
if (IOS::HLE::IPC_SUCCESS !=
es->VerifyContainer(IOS::HLE::Device::ES::VerifyContainerType::Ticket,
IOS::HLE::Device::ES::VerifyMode::DoNotUpdateCertStore, m_ticket,
cert_chain))
{
// i18n: "Ticket" here is a kind of digital authorization to use a certain title (e.g. a game)
AddProblem(Severity::Low, Common::GetStringT("The ticket is not correctly signed."));
}
if (IOS::HLE::IPC_SUCCESS !=
es->VerifyContainer(IOS::HLE::Device::ES::VerifyContainerType::TMD,
IOS::HLE::Device::ES::VerifyMode::DoNotUpdateCertStore, tmd,
cert_chain))
{
AddProblem(Severity::Low, Common::GetStringT("The TMD is not correctly signed."));
}
}
if (m_volume.IsNKit())
{
AddProblem(

View File

@ -148,7 +148,6 @@ private:
std::vector<Partition> CheckPartitions();
bool CheckPartition(const Partition& partition); // Returns false if partition should be ignored
std::string GetPartitionName(std::optional<u32> type) const;
void CheckCorrectlySigned(const Partition& partition, std::string error_text);
bool IsDebugSigned() const;
bool ShouldHaveChannelPartition() const;
bool ShouldHaveInstallPartition() const;