diff options
| author | shuffle2 <godisgovernment@gmail.com> | 2017-06-21 20:12:57 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-06-21 20:12:57 -0700 |
| commit | f65fe3efbd008907c5bb4919fab4901aef4df9dc (patch) | |
| tree | 65ca736ff395b8345b4ad9e014cdba21c698f6f1 /Source/Core | |
| parent | 4d0dd930981daa0638e3ed62dcb9ae5678af3fce (diff) | |
| parent | 5399311a13b0d5a5ab7149503da106acad9b336b (diff) | |
Merge pull request #5646 from Starsam80/cert-import-fixes
NANDImporter: Improve certificate extraction
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/DiscIO/NANDImporter.cpp | 81 | ||||
| -rw-r--r-- | Source/Core/DiscIO/NANDImporter.h | 2 |
2 files changed, 59 insertions, 24 deletions
diff --git a/Source/Core/DiscIO/NANDImporter.cpp b/Source/Core/DiscIO/NANDImporter.cpp index 1772b4f6f2..220a241390 100644 --- a/Source/Core/DiscIO/NANDImporter.cpp +++ b/Source/Core/DiscIO/NANDImporter.cpp @@ -4,6 +4,7 @@ #include "DiscIO/NANDImporter.h" +#include <algorithm> #include <array> #include <cinttypes> #include <cstring> @@ -15,6 +16,7 @@ #include "Common/MsgHandler.h" #include "Common/StringUtil.h" #include "Common/Swap.h" +#include "Core/IOS/ES/Formats.h" #include "DiscIO/NANDContentLoader.h" namespace DiscIO @@ -188,40 +190,73 @@ void NANDImporter::ProcessFile(const NANDFSTEntry& entry, const std::string& par } } -void NANDImporter::ExtractCertificates(const std::string& nand_root) +bool NANDImporter::ExtractCertificates(const std::string& nand_root) { - const std::string title_contents_path = - nand_root + "/title/00000001/0000000d/content/00000011.app"; - File::IOFile file(title_contents_path, "rb"); - if (!file) + const std::string content_dir = nand_root + "/title/00000001/0000000d/content/"; + + File::IOFile tmd_file(content_dir + "title.tmd", "rb"); + std::vector<u8> tmd_bytes(tmd_file.GetSize()); + if (!tmd_file.ReadBytes(tmd_bytes.data(), tmd_bytes.size())) { - PanicAlertT("Unable to open %s! Refer to " - "https://dolphin-emu.org/docs/guides/wii-network-guide/ to set up " - "certificates.", - title_contents_path.c_str()); - return; + ERROR_LOG(DISCIO, "ExtractCertificates: Could not read IOS13 TMD"); + return false; + } + + IOS::ES::TMDReader tmd(std::move(tmd_bytes)); + IOS::ES::Content content_metadata; + if (!tmd.GetContent(tmd.GetBootIndex(), &content_metadata)) + { + ERROR_LOG(DISCIO, "ExtractCertificates: Could not get content ID from TMD"); + return false; + } + + File::IOFile content_file(content_dir + StringFromFormat("%08x.app", content_metadata.id), "rb"); + std::vector<u8> content_bytes(content_file.GetSize()); + if (!content_file.ReadBytes(content_bytes.data(), content_bytes.size())) + { + ERROR_LOG(DISCIO, "ExtractCertificates: Could not read IOS13 contents"); + return false; } - struct Certificate + struct PEMCertificate { - u32 offset; - u32 size; std::string filename; + std::array<u8, 4> search_bytes; }; - std::array<Certificate, 3> certificates = {{{0x92834, 1005, "/clientca.pem"}, - {0x92d38, 609, "/clientcakey.pem"}, - {0x92440, 897, "/rootca.pem"}}}; - for (const Certificate& cert : certificates) + + std::array<PEMCertificate, 3> certificates = {{ + {"/clientca.pem", {{0x30, 0x82, 0x03, 0xE9}}}, + {"/clientcakey.pem", {{0x30, 0x82, 0x02, 0x5D}}}, + {"/rootca.pem", {{0x30, 0x82, 0x03, 0x7D}}}, + }}; + + for (const PEMCertificate& certificate : certificates) { - file.Seek(cert.offset, SEEK_SET); - std::vector<u8> pem_cert(cert.size); - file.ReadBytes(pem_cert.data(), pem_cert.size()); + const auto search_result = + std::search(content_bytes.begin(), content_bytes.end(), certificate.search_bytes.begin(), + certificate.search_bytes.end()); + + if (search_result == content_bytes.end()) + { + ERROR_LOG(DISCIO, "ExtractCertificates: Could not find offset for certficate '%s'", + certificate.filename.c_str()); + return false; + } + + const std::string pem_file_path = nand_root + certificate.filename; + const ptrdiff_t certificate_offset = std::distance(content_bytes.begin(), search_result); + const u16 certificate_size = Common::swap16(&content_bytes[certificate_offset - 2]); + INFO_LOG(DISCIO, "ExtractCertificates: '%s' offset: 0x%tx size: 0x%x", + certificate.filename.c_str(), certificate_offset, certificate_size); - const std::string pem_file_path = nand_root + cert.filename; File::IOFile pem_file(pem_file_path, "wb"); - if (!pem_file.WriteBytes(pem_cert.data(), pem_cert.size())) - PanicAlertT("Unable to write to file %s", pem_file_path.c_str()); + if (!pem_file.WriteBytes(&content_bytes[certificate_offset], certificate_size)) + { + ERROR_LOG(DISCIO, "ExtractCertificates: Unable to write to file %s", pem_file_path.c_str()); + return false; + } } + return true; } void NANDImporter::ExportKeys(const std::string& nand_root) diff --git a/Source/Core/DiscIO/NANDImporter.h b/Source/Core/DiscIO/NANDImporter.h index f079c2e82d..09ed7034cb 100644 --- a/Source/Core/DiscIO/NANDImporter.h +++ b/Source/Core/DiscIO/NANDImporter.h @@ -19,7 +19,7 @@ public: ~NANDImporter(); void ImportNANDBin(const std::string& path_to_bin, std::function<void()> update_callback); - void ExtractCertificates(const std::string& nand_root); + bool ExtractCertificates(const std::string& nand_root); private: #pragma pack(push, 1) |
