Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #12149 from noahpistilli/no-response-header-rsa
IOS/KD: Check if a file has an RSA signature
  • Loading branch information
AdmiralCurtiss committed Sep 3, 2023
2 parents 46a596c + fa2bc53 commit f063fb3
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 19 deletions.
5 changes: 5 additions & 0 deletions Source/Core/Core/IOS/Network/KD/NWC24DL.cpp
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/IOS/Network/KD/NWC24DL.h
Expand Up @@ -29,6 +29,7 @@ class NWC24Dl final

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;
Expand Down
54 changes: 35 additions & 19 deletions Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp
Expand Up @@ -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,
Expand Down

0 comments on commit f063fb3

Please sign in to comment.