diff options
| author | Sketch <75850871+SketchMaster2001@users.noreply.github.com> | 2023-08-31 22:36:47 -0400 |
|---|---|---|
| committer | Sketch <75850871+SketchMaster2001@users.noreply.github.com> | 2023-09-02 21:39:54 -0400 |
| commit | fa2bc535f10214963caf43068219da0fd3961dde (patch) | |
| tree | 833b1ab95066f28b342b03395e36846b1edf6e12 | |
| parent | 5e5887a378db28324a8fc8825f21539525412e12 (diff) | |
IOS/KD: Check if a file has an RSA signature
| -rw-r--r-- | Source/Core/Core/IOS/Network/KD/NWC24DL.cpp | 5 | ||||
| -rw-r--r-- | Source/Core/Core/IOS/Network/KD/NWC24DL.h | 1 | ||||
| -rw-r--r-- | Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp | 54 |
3 files changed, 41 insertions, 19 deletions
diff --git a/Source/Core/Core/IOS/Network/KD/NWC24DL.cpp b/Source/Core/Core/IOS/Network/KD/NWC24DL.cpp index 2dac60819d..e61f3abbf1 100644 --- a/Source/Core/Core/IOS/Network/KD/NWC24DL.cpp +++ b/Source/Core/Core/IOS/Network/KD/NWC24DL.cpp @@ -120,6 +120,11 @@ bool NWC24Dl::IsEncrypted(u16 entry_index) const return !!Common::ExtractBit(Common::swap32(m_data.entries[entry_index].flags), 3); } +bool NWC24Dl::IsRSASigned(u16 entry_index) const +{ + return !Common::ExtractBit(Common::swap32(m_data.entries[entry_index].flags), 2); +} + u32 NWC24Dl::Magic() const { return Common::swap32(m_data.header.magic); diff --git a/Source/Core/Core/IOS/Network/KD/NWC24DL.h b/Source/Core/Core/IOS/Network/KD/NWC24DL.h index 1704d15223..e5427ea2ea 100644 --- a/Source/Core/Core/IOS/Network/KD/NWC24DL.h +++ b/Source/Core/Core/IOS/Network/KD/NWC24DL.h @@ -29,6 +29,7 @@ public: bool DoesEntryExist(u16 entry_index); bool IsEncrypted(u16 entry_index) const; + bool IsRSASigned(u16 entry_index) const; std::string GetVFFContentName(u16 entry_index, std::optional<u8> subtask_id) const; std::string GetDownloadURL(u16 entry_index, std::optional<u8> subtask_id) const; std::string GetVFFPath(u16 entry_index) const; diff --git a/Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp b/Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp index b59c365155..856ce9860f 100644 --- a/Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp +++ b/Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp @@ -255,32 +255,48 @@ NWC24::ErrorCode NetKDRequestDevice::KDDownload(const u16 entry_index, return NWC24::WC24_ERR_SERVER; } - // Check if the filesize is smaller than the header size. - if (response->size() < sizeof(NWC24::WC24File)) + if (!m_dl_list.IsRSASigned(entry_index)) { - ERROR_LOG_FMT(IOS_WC24, "File at {} is too small to be a valid file.", url); - LogError(ErrorType::KD_Download, NWC24::WC24_ERR_BROKEN); - return NWC24::WC24_ERR_BROKEN; + // Data that is not signed with an RSA key will not have the WC24 header or 320 bytes before the + // actual data. We just have to make sure that the response is not empty. + if (response->empty()) + { + ERROR_LOG_FMT(IOS_WC24, "File at {} is empty.", url); + LogError(ErrorType::KD_Download, NWC24::WC24_ERR_BROKEN); + return NWC24::WC24_ERR_BROKEN; + } + + file_data = *response; } + else + { + // Check if the filesize is smaller than the header size. + if (response->size() < sizeof(NWC24::WC24File)) + { + ERROR_LOG_FMT(IOS_WC24, "File at {} is too small to be a valid file.", url); + LogError(ErrorType::KD_Download, NWC24::WC24_ERR_BROKEN); + return NWC24::WC24_ERR_BROKEN; + } - // Now we read the file - NWC24::WC24File wc24File; - std::memcpy(&wc24File, response->data(), sizeof(NWC24::WC24File)); + // Now we read the file + NWC24::WC24File wc24_file; + std::memcpy(&wc24_file, response->data(), sizeof(NWC24::WC24File)); - std::vector<u8> temp_buffer(response->begin() + 320, response->end()); + std::vector<u8> temp_buffer(response->begin() + 320, response->end()); - if (m_dl_list.IsEncrypted(entry_index)) - { - NWC24::WC24PubkMod pubkMod = m_dl_list.GetWC24PubkMod(entry_index); + if (m_dl_list.IsEncrypted(entry_index)) + { + NWC24::WC24PubkMod pubk_mod = m_dl_list.GetWC24PubkMod(entry_index); - file_data = std::vector<u8>(response->size() - 320); + file_data = std::vector<u8>(response->size() - 320); - Common::AES::CryptOFB(pubkMod.aes_key, wc24File.iv, wc24File.iv, temp_buffer.data(), - file_data.data(), temp_buffer.size()); - } - else - { - file_data = std::move(temp_buffer); + Common::AES::CryptOFB(pubk_mod.aes_key, wc24_file.iv, wc24_file.iv, temp_buffer.data(), + file_data.data(), temp_buffer.size()); + } + else + { + file_data = std::move(temp_buffer); + } } NWC24::ErrorCode reply = IOS::HLE::NWC24::OpenVFF(m_dl_list.GetVFFPath(entry_index), content_name, |
