From 4304f5f7fcae4ed1ec723ea83b4c0772e2f211f7 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Fri, 19 Jul 2019 19:42:42 +0200 Subject: [PATCH 1/3] Remove "not signed by Nintendo" warning when installing WADs Apparently nobody is using good dumps, meaning that the warning is a nuisance rather than useful information for most people. Especially so for people who don't install WADs permanently. It is still possible to verify the signature using the Verify tab of the game properties, which matches how Dolphin handles checking the signatures of Wii discs. --- Source/Core/Core/WiiUtils.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/WiiUtils.cpp b/Source/Core/Core/WiiUtils.cpp index c8e8bf9b20..7318448430 100644 --- a/Source/Core/Core/WiiUtils.cpp +++ b/Source/Core/Core/WiiUtils.cpp @@ -59,7 +59,10 @@ static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad) IOS::HLE::Device::ES::Context context; IOS::HLE::ReturnCode ret; + + // A lot of people use fakesigned WADs, so disable signature checking temporarily when installing const bool checks_enabled = SConfig::GetInstance().m_enable_signature_checks; + SConfig::GetInstance().m_enable_signature_checks = false; IOS::ES::TicketReader ticket = wad.GetTicket(); // Ensure the common key index is correct, as it's checked by IOS. @@ -69,13 +72,6 @@ static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad) IOS::HLE::Device::ES::TicketImportType::Unpersonalised)) < 0 || (ret = es->ImportTitleInit(context, tmd.GetBytes(), wad.GetCertificateChain())) < 0) { - if (checks_enabled && ret == IOS::HLE::IOSC_FAIL_CHECKVALUE && - AskYesNoT("This WAD has not been signed by Nintendo. Continue to import?")) - { - SConfig::GetInstance().m_enable_signature_checks = false; - continue; - } - if (ret != IOS::HLE::IOSC_FAIL_CHECKVALUE) PanicAlertT("WAD installation failed: Could not initialise title import (error %d).", ret); SConfig::GetInstance().m_enable_signature_checks = checks_enabled; From 732d157011f16b9ecf9ac59fa8f580af3bb97984 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Fri, 19 Jul 2019 19:59:10 +0200 Subject: [PATCH 2/3] Remove the EnableSignatureChecks setting Since Dolphin can do NUS downloads over plain HTTP, we really don't want people to be able to silently disable signature verification indefinitely. Removing the setting shouldn't have any significant negative impact now that signature verification always is disabled when installing WAD files. --- Source/Core/Core/Config/MainSettings.cpp | 2 - Source/Core/Core/Config/MainSettings.h | 1 - Source/Core/Core/ConfigManager.cpp | 2 - Source/Core/Core/ConfigManager.h | 2 - Source/Core/Core/IOS/ES/ES.cpp | 6 --- Source/Core/Core/IOS/ES/ES.h | 11 ++++- Source/Core/Core/IOS/ES/Identity.cpp | 6 --- Source/Core/Core/IOS/ES/TitleManagement.cpp | 47 +++++++++++++-------- Source/Core/Core/WiiUtils.cpp | 12 ++---- 9 files changed, 42 insertions(+), 47 deletions(-) diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp index 4176500314..55c84ca98f 100644 --- a/Source/Core/Core/Config/MainSettings.cpp +++ b/Source/Core/Core/Config/MainSettings.cpp @@ -101,8 +101,6 @@ const ConfigInfo MAIN_PERF_MAP_DIR{{System::Main, "Core", "PerfMapD const ConfigInfo MAIN_CUSTOM_RTC_ENABLE{{System::Main, "Core", "EnableCustomRTC"}, false}; // Default to seconds between 1.1.1970 and 1.1.2000 const ConfigInfo MAIN_CUSTOM_RTC_VALUE{{System::Main, "Core", "CustomRTCValue"}, 946684800}; -const ConfigInfo MAIN_ENABLE_SIGNATURE_CHECKS{{System::Main, "Core", "EnableSignatureChecks"}, - true}; const ConfigInfo MAIN_REDUCE_POLLING_RATE{{System::Main, "Core", "ReducePollingRate"}, false}; const ConfigInfo MAIN_AUTO_DISC_CHANGE{{System::Main, "Core", "AutoDiscChange"}, false}; diff --git a/Source/Core/Core/Config/MainSettings.h b/Source/Core/Core/Config/MainSettings.h index f0726b550f..743b8ae5d4 100644 --- a/Source/Core/Core/Config/MainSettings.h +++ b/Source/Core/Core/Config/MainSettings.h @@ -76,7 +76,6 @@ extern const ConfigInfo MAIN_GPU_DETERMINISM_MODE; extern const ConfigInfo MAIN_PERF_MAP_DIR; extern const ConfigInfo MAIN_CUSTOM_RTC_ENABLE; extern const ConfigInfo MAIN_CUSTOM_RTC_VALUE; -extern const ConfigInfo MAIN_ENABLE_SIGNATURE_CHECKS; extern const ConfigInfo MAIN_REDUCE_POLLING_RATE; extern const ConfigInfo MAIN_AUTO_DISC_CHANGE; diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index 68cf1457a1..a0da82792d 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -242,7 +242,6 @@ void SConfig::SaveCoreSettings(IniFile& ini) core->Set("PerfMapDir", m_perfDir); core->Set("EnableCustomRTC", bEnableCustomRTC); core->Set("CustomRTCValue", m_customRTCValue); - core->Set("EnableSignatureChecks", m_enable_signature_checks); } void SConfig::SaveMovieSettings(IniFile& ini) @@ -529,7 +528,6 @@ void SConfig::LoadCoreSettings(IniFile& ini) core->Get("EnableCustomRTC", &bEnableCustomRTC, false); // Default to seconds between 1.1.1970 and 1.1.2000 core->Get("CustomRTCValue", &m_customRTCValue, 946684800); - core->Get("EnableSignatureChecks", &m_enable_signature_checks, true); } void SConfig::LoadMovieSettings(IniFile& ini) diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h index 11c27f2f1a..38f178d221 100644 --- a/Source/Core/Core/ConfigManager.h +++ b/Source/Core/Core/ConfigManager.h @@ -166,8 +166,6 @@ struct SConfig std::set> m_usb_passthrough_devices; bool IsUSBDeviceWhitelisted(std::pair vid_pid) const; - bool m_enable_signature_checks = true; - // Fifo Player related settings bool bLoopFifoReplay = true; diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp index 8d1f9a9898..866bef39a0 100644 --- a/Source/Core/Core/IOS/ES/ES.cpp +++ b/Source/Core/Core/IOS/ES/ES.cpp @@ -841,9 +841,6 @@ static const std::string CERT_STORE_PATH = "/sys/cert.sys"; ReturnCode ES::ReadCertStore(std::vector* buffer) const { - if (!SConfig::GetInstance().m_enable_signature_checks) - return IPC_SUCCESS; - const auto store_file = m_ios.GetFS()->OpenFile(PID_KERNEL, PID_KERNEL, CERT_STORE_PATH, FS::Mode::Read); if (!store_file) @@ -884,9 +881,6 @@ ReturnCode ES::VerifyContainer(VerifyContainerType type, VerifyMode mode, const IOS::ES::SignedBlobReader& signed_blob, const std::vector& cert_chain, u32* issuer_handle_out) { - if (!SConfig::GetInstance().m_enable_signature_checks) - return IPC_SUCCESS; - if (!signed_blob.IsSignatureValid()) return ES_EINVAL; diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h index 89c47a90c7..41fc43402c 100644 --- a/Source/Core/Core/IOS/ES/ES.h +++ b/Source/Core/Core/IOS/ES/ES.h @@ -104,11 +104,18 @@ public: // Ticket is unpersonalised, so ignore any console specific decryption data. Unpersonalised, }; + enum class VerifySignature + { + No, + Yes, + }; ReturnCode ImportTicket(const std::vector& ticket_bytes, const std::vector& cert_chain, - TicketImportType type = TicketImportType::PossiblyPersonalised); + TicketImportType type = TicketImportType::PossiblyPersonalised, + VerifySignature verify_signature = VerifySignature::Yes); ReturnCode ImportTmd(Context& context, const std::vector& tmd_bytes); ReturnCode ImportTitleInit(Context& context, const std::vector& tmd_bytes, - const std::vector& cert_chain); + const std::vector& cert_chain, + VerifySignature verify_signature = VerifySignature::Yes); ReturnCode ImportContentBegin(Context& context, u64 title_id, u32 content_id); ReturnCode ImportContentData(Context& context, u32 content_fd, const u8* data, u32 data_size); ReturnCode ImportContentEnd(Context& context, u32 content_fd); diff --git a/Source/Core/Core/IOS/ES/Identity.cpp b/Source/Core/Core/IOS/ES/Identity.cpp index fd2ea1b9f5..1635202876 100644 --- a/Source/Core/Core/IOS/ES/Identity.cpp +++ b/Source/Core/Core/IOS/ES/Identity.cpp @@ -120,12 +120,6 @@ IPCCommandResult ES::Sign(const IOCtlVRequest& request) ReturnCode ES::VerifySign(const std::vector& hash, const std::vector& ecc_signature, const std::vector& certs_bytes) { - if (!SConfig::GetInstance().m_enable_signature_checks) - { - WARN_LOG(IOS_ES, "VerifySign: signature checks are disabled. Skipping."); - return IPC_SUCCESS; - } - const std::map certs = IOS::ES::ParseCertChain(certs_bytes); if (certs.empty()) return ES_EINVAL; diff --git a/Source/Core/Core/IOS/ES/TitleManagement.cpp b/Source/Core/Core/IOS/ES/TitleManagement.cpp index d415e44f2a..1ac9b23180 100644 --- a/Source/Core/Core/IOS/ES/TitleManagement.cpp +++ b/Source/Core/Core/IOS/ES/TitleManagement.cpp @@ -51,7 +51,7 @@ void ES::TitleImportExportContext::DoState(PointerWrap& p) } ReturnCode ES::ImportTicket(const std::vector& ticket_bytes, const std::vector& cert_chain, - TicketImportType type) + TicketImportType type, VerifySignature verify_signature) { IOS::ES::TicketReader ticket{ticket_bytes}; if (!ticket.IsValid()) @@ -75,10 +75,13 @@ ReturnCode ES::ImportTicket(const std::vector& ticket_bytes, const std::vect } } - const ReturnCode verify_ret = - VerifyContainer(VerifyContainerType::Ticket, VerifyMode::UpdateCertStore, ticket, cert_chain); - if (verify_ret != IPC_SUCCESS) - return verify_ret; + if (verify_signature != VerifySignature::No) + { + const ReturnCode verify_ret = VerifyContainer(VerifyContainerType::Ticket, + VerifyMode::UpdateCertStore, ticket, cert_chain); + if (verify_ret != IPC_SUCCESS) + return verify_ret; + } const ReturnCode write_ret = WriteTicket(m_ios.GetFS().get(), ticket); if (write_ret != IPC_SUCCESS) @@ -207,7 +210,7 @@ static ReturnCode InitTitleImportKey(const std::vector& ticket_bytes, IOSC& } ReturnCode ES::ImportTitleInit(Context& context, const std::vector& tmd_bytes, - const std::vector& cert_chain) + const std::vector& cert_chain, VerifySignature verify_signature) { INFO_LOG(IOS_ES, "ImportTitleInit"); ResetTitleImportContext(&context, m_ios.GetIOSC()); @@ -221,24 +224,32 @@ ReturnCode ES::ImportTitleInit(Context& context, const std::vector& tmd_byte // Finish a previous import (if it exists). FinishStaleImport(context.title_import_export.tmd.GetTitleId()); - ReturnCode ret = VerifyContainer(VerifyContainerType::TMD, VerifyMode::UpdateCertStore, - context.title_import_export.tmd, cert_chain); - if (ret != IPC_SUCCESS) - return ret; + ReturnCode ret = IPC_SUCCESS; + + if (verify_signature != VerifySignature::No) + { + ret = VerifyContainer(VerifyContainerType::TMD, VerifyMode::UpdateCertStore, + context.title_import_export.tmd, cert_chain); + if (ret != IPC_SUCCESS) + return ret; + } const auto ticket = FindSignedTicket(context.title_import_export.tmd.GetTitleId()); if (!ticket.IsValid()) return ES_NO_TICKET; - std::vector cert_store; - ret = ReadCertStore(&cert_store); - if (ret != IPC_SUCCESS) - return ret; + if (verify_signature != VerifySignature::No) + { + std::vector cert_store; + ret = ReadCertStore(&cert_store); + if (ret != IPC_SUCCESS) + return ret; - ret = VerifyContainer(VerifyContainerType::Ticket, VerifyMode::DoNotUpdateCertStore, ticket, - cert_store); - if (ret != IPC_SUCCESS) - return ret; + ret = VerifyContainer(VerifyContainerType::Ticket, VerifyMode::DoNotUpdateCertStore, ticket, + cert_store); + if (ret != IPC_SUCCESS) + return ret; + } ret = InitTitleImportKey(ticket.GetBytes(), m_ios.GetIOSC(), &context.title_import_export.key_handle); diff --git a/Source/Core/Core/WiiUtils.cpp b/Source/Core/Core/WiiUtils.cpp index 7318448430..792934ed50 100644 --- a/Source/Core/Core/WiiUtils.cpp +++ b/Source/Core/Core/WiiUtils.cpp @@ -60,24 +60,20 @@ static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad) IOS::HLE::Device::ES::Context context; IOS::HLE::ReturnCode ret; - // A lot of people use fakesigned WADs, so disable signature checking temporarily when installing - const bool checks_enabled = SConfig::GetInstance().m_enable_signature_checks; - SConfig::GetInstance().m_enable_signature_checks = false; - IOS::ES::TicketReader ticket = wad.GetTicket(); // Ensure the common key index is correct, as it's checked by IOS. ticket.FixCommonKeyIndex(); while ((ret = es->ImportTicket(ticket.GetBytes(), wad.GetCertificateChain(), - IOS::HLE::Device::ES::TicketImportType::Unpersonalised)) < 0 || - (ret = es->ImportTitleInit(context, tmd.GetBytes(), wad.GetCertificateChain())) < 0) + IOS::HLE::Device::ES::TicketImportType::Unpersonalised, + IOS::HLE::Device::ES::VerifySignature::No)) < 0 || + (ret = es->ImportTitleInit(context, tmd.GetBytes(), wad.GetCertificateChain(), + IOS::HLE::Device::ES::VerifySignature::No)) < 0) { if (ret != IOS::HLE::IOSC_FAIL_CHECKVALUE) PanicAlertT("WAD installation failed: Could not initialise title import (error %d).", ret); - SConfig::GetInstance().m_enable_signature_checks = checks_enabled; return false; } - SConfig::GetInstance().m_enable_signature_checks = checks_enabled; const bool contents_imported = [&]() { const u64 title_id = tmd.GetTitleId(); From a8807e7452389b0461174868c0d69ab013601145 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Fri, 19 Jul 2019 20:05:03 +0200 Subject: [PATCH 3/3] Force signature verification during system update from disc Unlike the WADs people put in their game lists, these WADs should always be correctly signed. --- Source/Core/Core/WiiUtils.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Source/Core/Core/WiiUtils.cpp b/Source/Core/Core/WiiUtils.cpp index 792934ed50..75ed6efed0 100644 --- a/Source/Core/Core/WiiUtils.cpp +++ b/Source/Core/Core/WiiUtils.cpp @@ -46,7 +46,8 @@ namespace WiiUtils { -static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad) +static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad, + IOS::HLE::Device::ES::VerifySignature verify_signature) { if (!wad.GetTicket().IsValid() || !wad.GetTMD().IsValid()) { @@ -66,9 +67,9 @@ static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad) while ((ret = es->ImportTicket(ticket.GetBytes(), wad.GetCertificateChain(), IOS::HLE::Device::ES::TicketImportType::Unpersonalised, - IOS::HLE::Device::ES::VerifySignature::No)) < 0 || + verify_signature)) < 0 || (ret = es->ImportTitleInit(context, tmd.GetBytes(), wad.GetCertificateChain(), - IOS::HLE::Device::ES::VerifySignature::No)) < 0) + verify_signature)) < 0) { if (ret != IOS::HLE::IOSC_FAIL_CHECKVALUE) PanicAlertT("WAD installation failed: Could not initialise title import (error %d).", ret); @@ -141,7 +142,8 @@ bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad, InstallType if (previous_temporary_title_id) ios.GetES()->DeleteTitleContent(previous_temporary_title_id); - if (!ImportWAD(ios, wad)) + // A lot of people use fakesigned WADs, so disable signature checking when installing a WAD. + if (!ImportWAD(ios, wad, IOS::HLE::Device::ES::VerifySignature::No)) return false; // Keep track of the title ID so this title can be removed to make room for any future install. @@ -731,7 +733,8 @@ UpdateResult DiscSystemUpdater::ProcessEntry(u32 type, std::bitset<32> attrs, return UpdateResult::DiscReadFailed; } const DiscIO::VolumeWAD wad{std::move(blob)}; - return ImportWAD(m_ios, wad) ? UpdateResult::Succeeded : UpdateResult::ImportFailed; + const bool success = ImportWAD(m_ios, wad, IOS::HLE::Device::ES::VerifySignature::Yes); + return success ? UpdateResult::Succeeded : UpdateResult::ImportFailed; } UpdateResult DoOnlineUpdate(UpdateCallback update_callback, const std::string& region)