forked from suyu/suyu
card_image: Parse XCI secure partition with NSP
Eliminated duplicate code and adds support for Rev1+ carts
This commit is contained in:
parent
93703431e2
commit
5c8aff984e
4 changed files with 38 additions and 11 deletions
|
@ -17,6 +17,8 @@ enum class ResultStatus : u16;
|
||||||
|
|
||||||
namespace Core::Crypto {
|
namespace Core::Crypto {
|
||||||
|
|
||||||
|
constexpr u64 TICKET_FILE_TITLEKEY_OFFSET = 0x180;
|
||||||
|
|
||||||
using Key128 = std::array<u8, 0x10>;
|
using Key128 = std::array<u8, 0x10>;
|
||||||
using Key256 = std::array<u8, 0x20>;
|
using Key256 = std::array<u8, 0x20>;
|
||||||
using SHA256Hash = std::array<u8, 0x20>;
|
using SHA256Hash = std::array<u8, 0x20>;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/file_sys/card_image.h"
|
#include "core/file_sys/card_image.h"
|
||||||
#include "core/file_sys/content_archive.h"
|
#include "core/file_sys/content_archive.h"
|
||||||
|
#include "core/file_sys/nca_metadata.h"
|
||||||
#include "core/file_sys/partition_filesystem.h"
|
#include "core/file_sys/partition_filesystem.h"
|
||||||
#include "core/file_sys/vfs_offset.h"
|
#include "core/file_sys/vfs_offset.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
|
@ -44,15 +45,19 @@ XCI::XCI(VirtualFile file_) : file(std::move(file_)), partitions(0x4) {
|
||||||
partitions[static_cast<size_t>(partition)] = std::make_shared<PartitionFilesystem>(raw);
|
partitions[static_cast<size_t>(partition)] = std::make_shared<PartitionFilesystem>(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
secure_partition = std::make_shared<NSP>(
|
||||||
|
main_hfs.GetFile(partition_names[static_cast<size_t>(XCIPartition::Secure)]));
|
||||||
|
|
||||||
|
const auto secure_ncas = secure_partition->GetNCAsCollapsed();
|
||||||
|
std::copy(secure_ncas.begin(), secure_ncas.end(), std::back_inserter(ncas));
|
||||||
|
|
||||||
program_nca_status = Loader::ResultStatus::ErrorXCIMissingProgramNCA;
|
program_nca_status = Loader::ResultStatus::ErrorXCIMissingProgramNCA;
|
||||||
|
program =
|
||||||
|
secure_partition->GetNCA(secure_partition->GetProgramTitleID(), ContentRecordType::Program);
|
||||||
|
if (program != nullptr)
|
||||||
|
program_nca_status = program->GetStatus();
|
||||||
|
|
||||||
auto result = AddNCAFromPartition(XCIPartition::Secure);
|
auto result = AddNCAFromPartition(XCIPartition::Update);
|
||||||
if (result != Loader::ResultStatus::Success) {
|
|
||||||
status = result;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = AddNCAFromPartition(XCIPartition::Update);
|
|
||||||
if (result != Loader::ResultStatus::Success) {
|
if (result != Loader::ResultStatus::Success) {
|
||||||
status = result;
|
status = result;
|
||||||
return;
|
return;
|
||||||
|
@ -89,6 +94,10 @@ VirtualDir XCI::GetPartition(XCIPartition partition) const {
|
||||||
return partitions[static_cast<size_t>(partition)];
|
return partitions[static_cast<size_t>(partition)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<NSP> XCI::GetSecurePartitionNSP() const {
|
||||||
|
return secure_partition;
|
||||||
|
}
|
||||||
|
|
||||||
VirtualDir XCI::GetSecurePartition() const {
|
VirtualDir XCI::GetSecurePartition() const {
|
||||||
return GetPartition(XCIPartition::Secure);
|
return GetPartition(XCIPartition::Secure);
|
||||||
}
|
}
|
||||||
|
@ -105,6 +114,16 @@ VirtualDir XCI::GetLogoPartition() const {
|
||||||
return GetPartition(XCIPartition::Logo);
|
return GetPartition(XCIPartition::Logo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<NCA> XCI::GetProgramNCA() const {
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
|
||||||
|
VirtualFile XCI::GetProgramNCAFile() const {
|
||||||
|
if (GetProgramNCA() == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
return GetProgramNCA()->GetBaseFile();
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<std::shared_ptr<NCA>>& XCI::GetNCAs() const {
|
const std::vector<std::shared_ptr<NCA>>& XCI::GetNCAs() const {
|
||||||
return ncas;
|
return ncas;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs.h"
|
||||||
|
#include "core/loader/loader.h"
|
||||||
|
#include "submission_package.h"
|
||||||
|
|
||||||
namespace Loader {
|
namespace Loader {
|
||||||
enum class ResultStatus : u16;
|
enum class ResultStatus : u16;
|
||||||
|
@ -71,11 +73,14 @@ public:
|
||||||
u8 GetFormatVersion() const;
|
u8 GetFormatVersion() const;
|
||||||
|
|
||||||
VirtualDir GetPartition(XCIPartition partition) const;
|
VirtualDir GetPartition(XCIPartition partition) const;
|
||||||
|
std::shared_ptr<NSP> GetSecurePartitionNSP() const;
|
||||||
VirtualDir GetSecurePartition() const;
|
VirtualDir GetSecurePartition() const;
|
||||||
VirtualDir GetNormalPartition() const;
|
VirtualDir GetNormalPartition() const;
|
||||||
VirtualDir GetUpdatePartition() const;
|
VirtualDir GetUpdatePartition() const;
|
||||||
VirtualDir GetLogoPartition() const;
|
VirtualDir GetLogoPartition() const;
|
||||||
|
|
||||||
|
std::shared_ptr<NCA> GetProgramNCA() const;
|
||||||
|
VirtualFile GetProgramNCAFile() const;
|
||||||
const std::vector<std::shared_ptr<NCA>>& GetNCAs() const;
|
const std::vector<std::shared_ptr<NCA>>& GetNCAs() const;
|
||||||
std::shared_ptr<NCA> GetNCAByType(NCAContentType type) const;
|
std::shared_ptr<NCA> GetNCAByType(NCAContentType type) const;
|
||||||
VirtualFile GetNCAFileByType(NCAContentType type) const;
|
VirtualFile GetNCAFileByType(NCAContentType type) const;
|
||||||
|
@ -101,6 +106,8 @@ private:
|
||||||
Loader::ResultStatus program_nca_status;
|
Loader::ResultStatus program_nca_status;
|
||||||
|
|
||||||
std::vector<VirtualDir> partitions;
|
std::vector<VirtualDir> partitions;
|
||||||
|
std::shared_ptr<NSP> secure_partition;
|
||||||
|
std::shared_ptr<NCA> program;
|
||||||
std::vector<std::shared_ptr<NCA>> ncas;
|
std::vector<std::shared_ptr<NCA>> ncas;
|
||||||
};
|
};
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|
|
@ -17,8 +17,7 @@ namespace Loader {
|
||||||
|
|
||||||
AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file)
|
AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file)
|
||||||
: AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)),
|
: AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)),
|
||||||
nca_loader(std::make_unique<AppLoader_NCA>(
|
nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) {
|
||||||
xci->GetNCAFileByType(FileSys::NCAContentType::Program))) {
|
|
||||||
if (xci->GetStatus() != ResultStatus::Success)
|
if (xci->GetStatus() != ResultStatus::Success)
|
||||||
return;
|
return;
|
||||||
const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control);
|
const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control);
|
||||||
|
@ -64,11 +63,11 @@ ResultStatus AppLoader_XCI::Load(Kernel::SharedPtr<Kernel::Process>& process) {
|
||||||
if (xci->GetProgramNCAStatus() != ResultStatus::Success)
|
if (xci->GetProgramNCAStatus() != ResultStatus::Success)
|
||||||
return xci->GetProgramNCAStatus();
|
return xci->GetProgramNCAStatus();
|
||||||
|
|
||||||
const auto nca = xci->GetNCAFileByType(FileSys::NCAContentType::Program);
|
const auto nca = xci->GetProgramNCA();
|
||||||
if (nca == nullptr && !Core::Crypto::KeyManager::KeyFileExists(false))
|
if (nca == nullptr && !Core::Crypto::KeyManager::KeyFileExists(false))
|
||||||
return ResultStatus::ErrorMissingProductionKeyFile;
|
return ResultStatus::ErrorMissingProductionKeyFile;
|
||||||
|
|
||||||
auto result = nca_loader->Load(process);
|
const auto result = nca_loader->Load(process);
|
||||||
if (result != ResultStatus::Success)
|
if (result != ResultStatus::Success)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue