IOS/ESFormats: Use SignedBlobReader for TMDs and tickets
This commit is contained in:
parent
2ec04675c9
commit
6c3069be97
|
@ -110,7 +110,7 @@ IPCCommandResult DI::IOCtlV(const IOCtlVRequest& request)
|
|||
|
||||
// Read TMD to the buffer
|
||||
const IOS::ES::TMDReader tmd = DVDThread::GetTMD(partition);
|
||||
const std::vector<u8> raw_tmd = tmd.GetRawTMD();
|
||||
const std::vector<u8>& raw_tmd = tmd.GetBytes();
|
||||
Memory::CopyToEmu(request.io_vectors[0].address, raw_tmd.data(), raw_tmd.size());
|
||||
ES::DIVerify(tmd, DVDThread::GetTicket(partition));
|
||||
|
||||
|
|
|
@ -610,7 +610,7 @@ s32 ES::DIVerify(const IOS::ES::TMDReader& tmd, const IOS::ES::TicketReader& tic
|
|||
if (!File::Exists(tmd_path))
|
||||
{
|
||||
File::IOFile tmd_file(tmd_path, "wb");
|
||||
const std::vector<u8>& tmd_bytes = tmd.GetRawTMD();
|
||||
const std::vector<u8>& tmd_bytes = tmd.GetBytes();
|
||||
if (!tmd_file.WriteBytes(tmd_bytes.data(), tmd_bytes.size()))
|
||||
ERROR_LOG(IOS_ES, "DIVerify failed to write disc TMD to NAND.");
|
||||
}
|
||||
|
|
|
@ -164,26 +164,19 @@ bool IsValidTMDSize(size_t size)
|
|||
return size <= 0x49e4;
|
||||
}
|
||||
|
||||
TMDReader::TMDReader(const std::vector<u8>& bytes) : m_bytes(bytes)
|
||||
TMDReader::TMDReader(const std::vector<u8>& bytes) : SignedBlobReader(bytes)
|
||||
{
|
||||
}
|
||||
|
||||
TMDReader::TMDReader(std::vector<u8>&& bytes) : m_bytes(std::move(bytes))
|
||||
TMDReader::TMDReader(std::vector<u8>&& bytes) : SignedBlobReader(std::move(bytes))
|
||||
{
|
||||
}
|
||||
|
||||
void TMDReader::SetBytes(const std::vector<u8>& bytes)
|
||||
{
|
||||
m_bytes = bytes;
|
||||
}
|
||||
|
||||
void TMDReader::SetBytes(std::vector<u8>&& bytes)
|
||||
{
|
||||
m_bytes = std::move(bytes);
|
||||
}
|
||||
|
||||
bool TMDReader::IsValid() const
|
||||
{
|
||||
if (!IsSignatureValid())
|
||||
return false;
|
||||
|
||||
if (m_bytes.size() < sizeof(TMDHeader))
|
||||
{
|
||||
// TMD is too small to contain its base fields.
|
||||
|
@ -199,11 +192,6 @@ bool TMDReader::IsValid() const
|
|||
return true;
|
||||
}
|
||||
|
||||
const std::vector<u8>& TMDReader::GetRawTMD() const
|
||||
{
|
||||
return m_bytes;
|
||||
}
|
||||
|
||||
std::vector<u8> TMDReader::GetRawHeader() const
|
||||
{
|
||||
return std::vector<u8>(m_bytes.begin(), m_bytes.begin() + sizeof(TMDHeader));
|
||||
|
@ -331,37 +319,17 @@ bool TMDReader::FindContentById(u32 id, Content* content) const
|
|||
return false;
|
||||
}
|
||||
|
||||
void TMDReader::DoState(PointerWrap& p)
|
||||
{
|
||||
p.Do(m_bytes);
|
||||
}
|
||||
|
||||
TicketReader::TicketReader(const std::vector<u8>& bytes) : m_bytes(bytes)
|
||||
TicketReader::TicketReader(const std::vector<u8>& bytes) : SignedBlobReader(bytes)
|
||||
{
|
||||
}
|
||||
|
||||
TicketReader::TicketReader(std::vector<u8>&& bytes) : m_bytes(std::move(bytes))
|
||||
TicketReader::TicketReader(std::vector<u8>&& bytes) : SignedBlobReader(std::move(bytes))
|
||||
{
|
||||
}
|
||||
|
||||
void TicketReader::SetBytes(const std::vector<u8>& bytes)
|
||||
{
|
||||
m_bytes = bytes;
|
||||
}
|
||||
|
||||
void TicketReader::SetBytes(std::vector<u8>&& bytes)
|
||||
{
|
||||
m_bytes = std::move(bytes);
|
||||
}
|
||||
|
||||
bool TicketReader::IsValid() const
|
||||
{
|
||||
return !m_bytes.empty() && m_bytes.size() % sizeof(Ticket) == 0;
|
||||
}
|
||||
|
||||
void TicketReader::DoState(PointerWrap& p)
|
||||
{
|
||||
p.Do(m_bytes);
|
||||
return IsSignatureValid() && !m_bytes.empty() && m_bytes.size() % sizeof(Ticket) == 0;
|
||||
}
|
||||
|
||||
size_t TicketReader::GetNumberOfTickets() const
|
||||
|
@ -369,11 +337,6 @@ size_t TicketReader::GetNumberOfTickets() const
|
|||
return m_bytes.size() / sizeof(Ticket);
|
||||
}
|
||||
|
||||
const std::vector<u8>& TicketReader::GetRawTicket() const
|
||||
{
|
||||
return m_bytes;
|
||||
}
|
||||
|
||||
std::vector<u8> TicketReader::GetRawTicket(u64 ticket_id_to_find) const
|
||||
{
|
||||
for (size_t i = 0; i < GetNumberOfTickets(); ++i)
|
||||
|
@ -404,13 +367,6 @@ std::vector<u8> TicketReader::GetRawTicketView(u32 ticket_num) const
|
|||
return view;
|
||||
}
|
||||
|
||||
std::string TicketReader::GetIssuer() const
|
||||
{
|
||||
const char* bytes =
|
||||
reinterpret_cast<const char*>(m_bytes.data() + offsetof(Ticket, signature.issuer));
|
||||
return std::string(bytes, strnlen(bytes, sizeof(Ticket::signature.issuer)));
|
||||
}
|
||||
|
||||
u32 TicketReader::GetDeviceId() const
|
||||
{
|
||||
return Common::swap32(m_bytes.data() + offsetof(Ticket, device_id));
|
||||
|
|
|
@ -169,20 +169,16 @@ protected:
|
|||
|
||||
bool IsValidTMDSize(size_t size);
|
||||
|
||||
class TMDReader final
|
||||
class TMDReader final : public SignedBlobReader
|
||||
{
|
||||
public:
|
||||
TMDReader() = default;
|
||||
explicit TMDReader(const std::vector<u8>& bytes);
|
||||
explicit TMDReader(std::vector<u8>&& bytes);
|
||||
|
||||
void SetBytes(const std::vector<u8>& bytes);
|
||||
void SetBytes(std::vector<u8>&& bytes);
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
// Returns the TMD or parts of it without any kind of parsing. Intended for use by ES.
|
||||
const std::vector<u8>& GetRawTMD() const;
|
||||
// Returns parts of the TMD without any kind of parsing. Intended for use by ES.
|
||||
std::vector<u8> GetRawHeader() const;
|
||||
std::vector<u8> GetRawView() const;
|
||||
|
||||
|
@ -203,27 +199,17 @@ public:
|
|||
bool GetContent(u16 index, Content* content) const;
|
||||
std::vector<Content> GetContents() const;
|
||||
bool FindContentById(u32 id, Content* content) const;
|
||||
|
||||
void DoState(PointerWrap& p);
|
||||
|
||||
private:
|
||||
std::vector<u8> m_bytes;
|
||||
};
|
||||
|
||||
class TicketReader final
|
||||
class TicketReader final : public SignedBlobReader
|
||||
{
|
||||
public:
|
||||
TicketReader() = default;
|
||||
explicit TicketReader(const std::vector<u8>& bytes);
|
||||
explicit TicketReader(std::vector<u8>&& bytes);
|
||||
|
||||
void SetBytes(const std::vector<u8>& bytes);
|
||||
void SetBytes(std::vector<u8>&& bytes);
|
||||
|
||||
bool IsValid() const;
|
||||
void DoState(PointerWrap& p);
|
||||
|
||||
const std::vector<u8>& GetRawTicket() const;
|
||||
std::vector<u8> GetRawTicket(u64 ticket_id) const;
|
||||
size_t GetNumberOfTickets() const;
|
||||
|
||||
|
@ -233,7 +219,6 @@ public:
|
|||
// more than just one ticket and generate ticket views for them, so we implement it too.
|
||||
std::vector<u8> GetRawTicketView(u32 ticket_num) const;
|
||||
|
||||
std::string GetIssuer() const;
|
||||
u32 GetDeviceId() const;
|
||||
u64 GetTitleId() const;
|
||||
std::vector<u8> GetTitleKey() const;
|
||||
|
@ -244,9 +229,6 @@ public:
|
|||
// Decrypts the title key field for a "personalised" ticket -- one that is device-specific
|
||||
// and has a title key that must be decrypted first.
|
||||
s32 Unpersonalise();
|
||||
|
||||
private:
|
||||
std::vector<u8> m_bytes;
|
||||
};
|
||||
|
||||
class SharedContentMap final
|
||||
|
|
|
@ -254,7 +254,7 @@ bool ES::WriteImportTMD(const IOS::ES::TMDReader& tmd)
|
|||
|
||||
{
|
||||
File::IOFile file(tmd_path, "wb");
|
||||
if (!file.WriteBytes(tmd.GetRawTMD().data(), tmd.GetRawTMD().size()))
|
||||
if (!file.WriteBytes(tmd.GetBytes().data(), tmd.GetBytes().size()))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ IPCCommandResult ES::GetStoredTMDSize(const IOCtlVRequest& request)
|
|||
if (!tmd.IsValid())
|
||||
return GetDefaultReply(FS_ENOENT);
|
||||
|
||||
const u32 tmd_size = static_cast<u32>(tmd.GetRawTMD().size());
|
||||
const u32 tmd_size = static_cast<u32>(tmd.GetBytes().size());
|
||||
Memory::Write_U32(tmd_size, request.io_vectors[0].address);
|
||||
|
||||
INFO_LOG(IOS_ES, "GetStoredTMDSize: %u bytes for %016" PRIx64, tmd_size, title_id);
|
||||
|
@ -171,7 +171,7 @@ IPCCommandResult ES::GetStoredTMD(const IOCtlVRequest& request)
|
|||
// TODO: actually use this param in when writing to the outbuffer :/
|
||||
const u32 MaxCount = Memory::Read_U32(request.in_vectors[1].address);
|
||||
|
||||
const std::vector<u8> raw_tmd = tmd.GetRawTMD();
|
||||
const std::vector<u8>& raw_tmd = tmd.GetBytes();
|
||||
if (raw_tmd.size() != request.io_vectors[0].size)
|
||||
return GetDefaultReply(ES_EINVAL);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ static ReturnCode WriteTicket(const IOS::ES::TicketReader& ticket)
|
|||
if (!ticket_file)
|
||||
return ES_EIO;
|
||||
|
||||
const std::vector<u8>& raw_ticket = ticket.GetRawTicket();
|
||||
const std::vector<u8>& raw_ticket = ticket.GetBytes();
|
||||
return ticket_file.WriteBytes(raw_ticket.data(), raw_ticket.size()) ? IPC_SUCCESS : ES_EIO;
|
||||
}
|
||||
|
||||
|
@ -394,7 +394,7 @@ ReturnCode ES::DeleteTicket(const u8* ticket_view)
|
|||
const u64 ticket_id = Common::swap64(ticket_view + offsetof(IOS::ES::TicketView, ticket_id));
|
||||
ticket.DeleteTicket(ticket_id);
|
||||
|
||||
const std::vector<u8>& new_ticket = ticket.GetRawTicket();
|
||||
const std::vector<u8>& new_ticket = ticket.GetBytes();
|
||||
const std::string ticket_path = Common::GetTicketFileName(title_id, Common::FROM_SESSION_ROOT);
|
||||
{
|
||||
File::IOFile ticket_file(ticket_path, "wb");
|
||||
|
@ -505,7 +505,7 @@ ReturnCode ES::ExportTitleInit(Context& context, u64 title_id, u8* tmd_bytes, u3
|
|||
|
||||
context.title_export.title_key = ticket.GetTitleKey();
|
||||
|
||||
const auto& raw_tmd = context.title_export.tmd.GetRawTMD();
|
||||
const std::vector<u8>& raw_tmd = context.title_export.tmd.GetBytes();
|
||||
if (tmd_size != raw_tmd.size())
|
||||
return ES_EINVAL;
|
||||
|
||||
|
|
|
@ -376,7 +376,7 @@ IPCCommandResult ES::DIGetTMDSize(const IOCtlVRequest& request)
|
|||
if (!GetTitleContext().active)
|
||||
return GetDefaultReply(ES_EINVAL);
|
||||
|
||||
Memory::Write_U32(static_cast<u32>(GetTitleContext().tmd.GetRawTMD().size()),
|
||||
Memory::Write_U32(static_cast<u32>(GetTitleContext().tmd.GetBytes().size()),
|
||||
request.io_vectors[0].address);
|
||||
return GetDefaultReply(IPC_SUCCESS);
|
||||
}
|
||||
|
@ -393,7 +393,7 @@ IPCCommandResult ES::DIGetTMD(const IOCtlVRequest& request)
|
|||
if (!GetTitleContext().active)
|
||||
return GetDefaultReply(ES_EINVAL);
|
||||
|
||||
const std::vector<u8>& tmd_bytes = GetTitleContext().tmd.GetRawTMD();
|
||||
const std::vector<u8>& tmd_bytes = GetTitleContext().tmd.GetBytes();
|
||||
|
||||
if (static_cast<u32>(tmd_bytes.size()) > tmd_size)
|
||||
return GetDefaultReply(ES_EINVAL);
|
||||
|
|
|
@ -27,8 +27,8 @@ bool InstallWAD(const std::string& wad_path)
|
|||
const auto es = ios.GetES();
|
||||
|
||||
IOS::HLE::Device::ES::Context context;
|
||||
if (es->ImportTicket(wad.GetTicket().GetRawTicket()) < 0 ||
|
||||
es->ImportTitleInit(context, tmd.GetRawTMD()) < 0)
|
||||
if (es->ImportTicket(wad.GetTicket().GetBytes()) < 0 ||
|
||||
es->ImportTitleInit(context, tmd.GetBytes()) < 0)
|
||||
{
|
||||
PanicAlertT("WAD installation failed: Could not initialise title import.");
|
||||
return false;
|
||||
|
|
|
@ -76,7 +76,7 @@ void TMDReaderTest::TestGeneralInfo()
|
|||
|
||||
void TMDReaderTest::TestRawTMDAndView()
|
||||
{
|
||||
const std::vector<u8>& dolphin_tmd_bytes = m_tmd.GetRawTMD();
|
||||
const std::vector<u8>& dolphin_tmd_bytes = m_tmd.GetBytes();
|
||||
// Separate check because gtest prints neither the size nor the full buffer.
|
||||
EXPECT_EQ(m_raw_tmd.size(), dolphin_tmd_bytes.size());
|
||||
EXPECT_EQ(m_raw_tmd, dolphin_tmd_bytes);
|
||||
|
|
Loading…
Reference in New Issue