summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorshuffle2 <godisgovernment@gmail.com>2017-06-21 20:12:57 -0700
committerGitHub <noreply@github.com>2017-06-21 20:12:57 -0700
commitf65fe3efbd008907c5bb4919fab4901aef4df9dc (patch)
tree65ca736ff395b8345b4ad9e014cdba21c698f6f1 /Source/Core
parent4d0dd930981daa0638e3ed62dcb9ae5678af3fce (diff)
parent5399311a13b0d5a5ab7149503da106acad9b336b (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.cpp81
-rw-r--r--Source/Core/DiscIO/NANDImporter.h2
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)