From 7ef0bc0359e159680ba27e53976bd025de9ae82a Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 8 Aug 2020 19:38:50 +0200 Subject: [PATCH] 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. --- Source/Core/DiscIO/VolumeVerifier.cpp | 67 +++++++++++++++++---------- Source/Core/DiscIO/VolumeVerifier.h | 1 - 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/Source/Core/DiscIO/VolumeVerifier.cpp b/Source/Core/DiscIO/VolumeVerifier.cpp index c1a2bcbd90..19bf2036cf 100644 --- a/Source/Core/DiscIO/VolumeVerifier.cpp +++ b/Source/Core/DiscIO/VolumeVerifier.cpp @@ -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& 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 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 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& 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( diff --git a/Source/Core/DiscIO/VolumeVerifier.h b/Source/Core/DiscIO/VolumeVerifier.h index b4df664337..1f045a2348 100644 --- a/Source/Core/DiscIO/VolumeVerifier.h +++ b/Source/Core/DiscIO/VolumeVerifier.h @@ -148,7 +148,6 @@ private: std::vector CheckPartitions(); bool CheckPartition(const Partition& partition); // Returns false if partition should be ignored std::string GetPartitionName(std::optional type) const; - void CheckCorrectlySigned(const Partition& partition, std::string error_text); bool IsDebugSigned() const; bool ShouldHaveChannelPartition() const; bool ShouldHaveInstallPartition() const;