Skip to content

Commit

Permalink
Merge pull request dolphin-emu#8255 from JosJuice/remove-unsigned-war…
Browse files Browse the repository at this point in the history
…ning

Remove "not signed by Nintendo" warning when installing WADs
  • Loading branch information
Helios747 authored Aug 21, 2019
2 parents 55d9f89 + a8807e7 commit 2a95227
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 54 deletions.
2 changes: 0 additions & 2 deletions Source/Core/Core/Config/MainSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,6 @@ const ConfigInfo<std::string> MAIN_PERF_MAP_DIR{{System::Main, "Core", "PerfMapD
const ConfigInfo<bool> MAIN_CUSTOM_RTC_ENABLE{{System::Main, "Core", "EnableCustomRTC"}, false};
// Default to seconds between 1.1.1970 and 1.1.2000
const ConfigInfo<u32> MAIN_CUSTOM_RTC_VALUE{{System::Main, "Core", "CustomRTCValue"}, 946684800};
const ConfigInfo<bool> MAIN_ENABLE_SIGNATURE_CHECKS{{System::Main, "Core", "EnableSignatureChecks"},
true};
const ConfigInfo<bool> MAIN_REDUCE_POLLING_RATE{{System::Main, "Core", "ReducePollingRate"}, false};
const ConfigInfo<bool> MAIN_AUTO_DISC_CHANGE{{System::Main, "Core", "AutoDiscChange"}, false};

Expand Down
1 change: 0 additions & 1 deletion Source/Core/Core/Config/MainSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ extern const ConfigInfo<std::string> MAIN_GPU_DETERMINISM_MODE;
extern const ConfigInfo<std::string> MAIN_PERF_MAP_DIR;
extern const ConfigInfo<bool> MAIN_CUSTOM_RTC_ENABLE;
extern const ConfigInfo<u32> MAIN_CUSTOM_RTC_VALUE;
extern const ConfigInfo<bool> MAIN_ENABLE_SIGNATURE_CHECKS;
extern const ConfigInfo<bool> MAIN_REDUCE_POLLING_RATE;
extern const ConfigInfo<bool> MAIN_AUTO_DISC_CHANGE;

Expand Down
2 changes: 0 additions & 2 deletions Source/Core/Core/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 0 additions & 2 deletions Source/Core/Core/ConfigManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,6 @@ struct SConfig
std::set<std::pair<u16, u16>> m_usb_passthrough_devices;
bool IsUSBDeviceWhitelisted(std::pair<u16, u16> vid_pid) const;

bool m_enable_signature_checks = true;

// Fifo Player related settings
bool bLoopFifoReplay = true;

Expand Down
6 changes: 0 additions & 6 deletions Source/Core/Core/IOS/ES/ES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -842,9 +842,6 @@ static const std::string CERT_STORE_PATH = "/sys/cert.sys";

ReturnCode ES::ReadCertStore(std::vector<u8>* 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)
Expand Down Expand Up @@ -885,9 +882,6 @@ ReturnCode ES::VerifyContainer(VerifyContainerType type, VerifyMode mode,
const IOS::ES::SignedBlobReader& signed_blob,
const std::vector<u8>& cert_chain, u32* issuer_handle_out)
{
if (!SConfig::GetInstance().m_enable_signature_checks)
return IPC_SUCCESS;

if (!signed_blob.IsSignatureValid())
return ES_EINVAL;

Expand Down
11 changes: 9 additions & 2 deletions Source/Core/Core/IOS/ES/ES.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,18 @@ class ES final : public Device
// Ticket is unpersonalised, so ignore any console specific decryption data.
Unpersonalised,
};
enum class VerifySignature
{
No,
Yes,
};
ReturnCode ImportTicket(const std::vector<u8>& ticket_bytes, const std::vector<u8>& cert_chain,
TicketImportType type = TicketImportType::PossiblyPersonalised);
TicketImportType type = TicketImportType::PossiblyPersonalised,
VerifySignature verify_signature = VerifySignature::Yes);
ReturnCode ImportTmd(Context& context, const std::vector<u8>& tmd_bytes);
ReturnCode ImportTitleInit(Context& context, const std::vector<u8>& tmd_bytes,
const std::vector<u8>& cert_chain);
const std::vector<u8>& 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);
Expand Down
6 changes: 0 additions & 6 deletions Source/Core/Core/IOS/ES/Identity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,6 @@ IPCCommandResult ES::Sign(const IOCtlVRequest& request)
ReturnCode ES::VerifySign(const std::vector<u8>& hash, const std::vector<u8>& ecc_signature,
const std::vector<u8>& 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<std::string, IOS::ES::CertReader> certs = IOS::ES::ParseCertChain(certs_bytes);
if (certs.empty())
return ES_EINVAL;
Expand Down
47 changes: 29 additions & 18 deletions Source/Core/Core/IOS/ES/TitleManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void ES::TitleImportExportContext::DoState(PointerWrap& p)
}

ReturnCode ES::ImportTicket(const std::vector<u8>& ticket_bytes, const std::vector<u8>& cert_chain,
TicketImportType type)
TicketImportType type, VerifySignature verify_signature)
{
IOS::ES::TicketReader ticket{ticket_bytes};
if (!ticket.IsValid())
Expand All @@ -75,10 +75,13 @@ ReturnCode ES::ImportTicket(const std::vector<u8>& 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)
Expand Down Expand Up @@ -206,7 +209,7 @@ static ReturnCode InitTitleImportKey(const std::vector<u8>& ticket_bytes, IOSC&
}

ReturnCode ES::ImportTitleInit(Context& context, const std::vector<u8>& tmd_bytes,
const std::vector<u8>& cert_chain)
const std::vector<u8>& cert_chain, VerifySignature verify_signature)
{
INFO_LOG(IOS_ES, "ImportTitleInit");
ResetTitleImportContext(&context, m_ios.GetIOSC());
Expand All @@ -220,24 +223,32 @@ ReturnCode ES::ImportTitleInit(Context& context, const std::vector<u8>& 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<u8> cert_store;
ret = ReadCertStore(&cert_store);
if (ret != IPC_SUCCESS)
return ret;
if (verify_signature != VerifySignature::No)
{
std::vector<u8> 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);
Expand Down
25 changes: 10 additions & 15 deletions Source/Core/Core/WiiUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
{
Expand All @@ -59,28 +60,20 @@ static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad)

IOS::HLE::Device::ES::Context context;
IOS::HLE::ReturnCode ret;
const bool checks_enabled = SConfig::GetInstance().m_enable_signature_checks;

// Ensure the common key index is correct, as it's checked by IOS.
IOS::ES::TicketReader ticket = wad.GetTicketWithFixedCommonKey();

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,
verify_signature)) < 0 ||
(ret = es->ImportTitleInit(context, tmd.GetBytes(), wad.GetCertificateChain(),
verify_signature)) < 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;
return false;
}
SConfig::GetInstance().m_enable_signature_checks = checks_enabled;

const bool contents_imported = [&]() {
const u64 title_id = tmd.GetTitleId();
Expand Down Expand Up @@ -148,7 +141,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.
Expand Down Expand Up @@ -738,7 +732,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)
Expand Down

0 comments on commit 2a95227

Please sign in to comment.