From 065867e2c24e9856c360fc2d6b9a86c92aedc43e Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Tue, 25 May 2021 19:32:56 -0400 Subject: common: fs: Rework the Common Filesystem interface to make use of std::filesystem (#6270) * common: fs: fs_types: Create filesystem types Contains various filesystem types used by the Common::FS library * common: fs: fs_util: Add std::string to std::u8string conversion utility * common: fs: path_util: Add utlity functions for paths Contains various utility functions for getting or manipulating filesystem paths used by the Common::FS library * common: fs: file: Rewrite the IOFile implementation * common: fs: Reimplement Common::FS library using std::filesystem * common: fs: fs_paths: Add fs_paths to replace common_paths * common: fs: path_util: Add the rest of the path functions * common: Remove the previous Common::FS implementation * general: Remove unused fs includes * string_util: Remove unused function and include * nvidia_flags: Migrate to the new Common::FS library * settings: Migrate to the new Common::FS library * logging: backend: Migrate to the new Common::FS library * core: Migrate to the new Common::FS library * perf_stats: Migrate to the new Common::FS library * reporter: Migrate to the new Common::FS library * telemetry_session: Migrate to the new Common::FS library * key_manager: Migrate to the new Common::FS library * bis_factory: Migrate to the new Common::FS library * registered_cache: Migrate to the new Common::FS library * xts_archive: Migrate to the new Common::FS library * service: acc: Migrate to the new Common::FS library * applets/profile: Migrate to the new Common::FS library * applets/web: Migrate to the new Common::FS library * service: filesystem: Migrate to the new Common::FS library * loader: Migrate to the new Common::FS library * gl_shader_disk_cache: Migrate to the new Common::FS library * nsight_aftermath_tracker: Migrate to the new Common::FS library * vulkan_library: Migrate to the new Common::FS library * configure_debug: Migrate to the new Common::FS library * game_list_worker: Migrate to the new Common::FS library * config: Migrate to the new Common::FS library * configure_filesystem: Migrate to the new Common::FS library * configure_per_game_addons: Migrate to the new Common::FS library * configure_profile_manager: Migrate to the new Common::FS library * configure_ui: Migrate to the new Common::FS library * input_profiles: Migrate to the new Common::FS library * yuzu_cmd: config: Migrate to the new Common::FS library * yuzu_cmd: Migrate to the new Common::FS library * vfs_real: Migrate to the new Common::FS library * vfs: Migrate to the new Common::FS library * vfs_libzip: Migrate to the new Common::FS library * service: bcat: Migrate to the new Common::FS library * yuzu: main: Migrate to the new Common::FS library * vfs_real: Delete the contents of an existing file in CreateFile Current usages of CreateFile expect to delete the contents of an existing file, retain this behavior for now. * input_profiles: Don't iterate the input profile dir if it does not exist Silences an error produced in the log if the directory does not exist. * game_list_worker: Skip parsing file if the returned VfsFile is nullptr Prevents crashes in GetLoader when the virtual file is nullptr * common: fs: Validate paths for path length * service: filesystem: Open the mod load directory as read only --- src/core/crypto/key_manager.cpp | 139 ++++++++++++++++++++++------------------ src/core/crypto/key_manager.h | 6 +- 2 files changed, 79 insertions(+), 66 deletions(-) (limited to 'src/core/crypto') diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index a4b739c63..fb451a423 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp @@ -18,8 +18,9 @@ #include #include #include "common/common_funcs.h" -#include "common/common_paths.h" -#include "common/file_util.h" +#include "common/fs/file.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" #include "common/hex_util.h" #include "common/logging/log.h" #include "common/settings.h" @@ -325,46 +326,55 @@ Key128 DeriveKeyblobMACKey(const Key128& keyblob_key, const Key128& mac_source) } std::optional DeriveSDSeed() { - const Common::FS::IOFile save_43(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir) + - "/system/save/8000000000000043", - "rb+"); + const auto system_save_43_path = + Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000043"; + const Common::FS::IOFile save_43{system_save_43_path, Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile}; + if (!save_43.IsOpen()) { return std::nullopt; } - const Common::FS::IOFile sd_private(Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir) + - "/Nintendo/Contents/private", - "rb+"); + const auto sd_private_path = + Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "Nintendo/Contents/private"; + + const Common::FS::IOFile sd_private{sd_private_path, Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile}; + if (!sd_private.IsOpen()) { return std::nullopt; } std::array private_seed{}; - if (sd_private.ReadBytes(private_seed.data(), private_seed.size()) != private_seed.size()) { + if (sd_private.Read(private_seed) != private_seed.size()) { return std::nullopt; } std::array buffer{}; - std::size_t offset = 0; - for (; offset + 0x10 < save_43.GetSize(); ++offset) { - if (!save_43.Seek(offset, SEEK_SET)) { + s64 offset = 0; + for (; offset + 0x10 < static_cast(save_43.GetSize()); ++offset) { + if (!save_43.Seek(offset)) { + return std::nullopt; + } + + if (save_43.Read(buffer) != buffer.size()) { return std::nullopt; } - save_43.ReadBytes(buffer.data(), buffer.size()); if (buffer == private_seed) { break; } } - if (!save_43.Seek(offset + 0x10, SEEK_SET)) { + if (!save_43.Seek(offset + 0x10)) { return std::nullopt; } Key128 seed{}; - if (save_43.ReadBytes(seed.data(), seed.size()) != seed.size()) { + if (save_43.Read(seed) != seed.size()) { return std::nullopt; } + return seed; } @@ -435,7 +445,7 @@ std::vector GetTicketblob(const Common::FS::IOFile& ticket_save) { } std::vector buffer(ticket_save.GetSize()); - if (ticket_save.ReadBytes(buffer.data(), buffer.size()) != buffer.size()) { + if (ticket_save.Read(buffer) != buffer.size()) { return {}; } @@ -566,27 +576,26 @@ std::optional> ParseTicket(const Ticket& ticket, KeyManager::KeyManager() { // Initialize keys - const std::string hactool_keys_dir = Common::FS::GetHactoolConfigurationPath(); - const std::string yuzu_keys_dir = Common::FS::GetUserPath(Common::FS::UserPath::KeysDir); + const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir); - if (!Common::FS::Exists(yuzu_keys_dir)) { - Common::FS::CreateDir(yuzu_keys_dir); + if (!Common::FS::CreateDir(yuzu_keys_dir)) { + LOG_ERROR(Core, "Failed to create the keys directory."); } if (Settings::values.use_dev_keys) { dev_mode = true; - AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "dev.keys", false); - AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "dev.keys_autogenerated", false); + LoadFromFile(yuzu_keys_dir / "dev.keys", false); + LoadFromFile(yuzu_keys_dir / "dev.keys_autogenerated", false); } else { dev_mode = false; - AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "prod.keys", false); - AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "prod.keys_autogenerated", false); + LoadFromFile(yuzu_keys_dir / "prod.keys", false); + LoadFromFile(yuzu_keys_dir / "prod.keys_autogenerated", false); } - AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "title.keys", true); - AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "title.keys_autogenerated", true); - AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "console.keys", false); - AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "console.keys_autogenerated", false); + LoadFromFile(yuzu_keys_dir / "title.keys", true); + LoadFromFile(yuzu_keys_dir / "title.keys_autogenerated", true); + LoadFromFile(yuzu_keys_dir / "console.keys", false); + LoadFromFile(yuzu_keys_dir / "console.keys_autogenerated", false); } static bool ValidCryptoRevisionString(std::string_view base, size_t begin, size_t length) { @@ -597,9 +606,14 @@ static bool ValidCryptoRevisionString(std::string_view base, size_t begin, size_ [](u8 c) { return std::isxdigit(c); }); } -void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) { +void KeyManager::LoadFromFile(const std::filesystem::path& file_path, bool is_title_keys) { + if (!Common::FS::Exists(file_path)) { + return; + } + std::ifstream file; - Common::FS::OpenFStream(file, filename, std::ios_base::in); + Common::FS::OpenFileStream(file, file_path, std::ios_base::in); + if (!file.is_open()) { return; } @@ -694,15 +708,6 @@ void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) { } } -void KeyManager::AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2, - const std::string& filename, bool title) { - if (Common::FS::Exists(dir1 + DIR_SEP + filename)) { - LoadFromFile(dir1 + DIR_SEP + filename, title); - } else if (Common::FS::Exists(dir2 + DIR_SEP + filename)) { - LoadFromFile(dir2 + DIR_SEP + filename, title); - } -} - bool KeyManager::BaseDeriveNecessary() const { const auto check_key_existence = [this](auto key_type, u64 index1 = 0, u64 index2 = 0) { return !HasKey(key_type, index1, index2); @@ -766,30 +771,35 @@ Key256 KeyManager::GetBISKey(u8 partition_id) const { template void KeyManager::WriteKeyToFile(KeyCategory category, std::string_view keyname, const std::array& key) { - const std::string yuzu_keys_dir = Common::FS::GetUserPath(Common::FS::UserPath::KeysDir); + const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir); + std::string filename = "title.keys_autogenerated"; + if (category == KeyCategory::Standard) { filename = dev_mode ? "dev.keys_autogenerated" : "prod.keys_autogenerated"; } else if (category == KeyCategory::Console) { filename = "console.keys_autogenerated"; } - const auto path = yuzu_keys_dir + DIR_SEP + filename; + const auto path = yuzu_keys_dir / filename; const auto add_info_text = !Common::FS::Exists(path); - Common::FS::CreateFullPath(path); - Common::FS::IOFile file{path, "a"}; + + Common::FS::IOFile file{path, Common::FS::FileAccessMode::Append, + Common::FS::FileType::TextFile}; + if (!file.IsOpen()) { return; } + if (add_info_text) { - file.WriteString( + void(file.WriteString( "# This file is autogenerated by Yuzu\n" "# It serves to store keys that were automatically generated from the normal keys\n" - "# If you are experiencing issues involving keys, it may help to delete this file\n"); + "# If you are experiencing issues involving keys, it may help to delete this file\n")); } - file.WriteString(fmt::format("\n{} = {}", keyname, Common::HexToString(key))); - AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, filename, category == KeyCategory::Title); + void(file.WriteString(fmt::format("\n{} = {}", keyname, Common::HexToString(key)))); + LoadFromFile(path, category == KeyCategory::Title); } void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) { @@ -861,20 +871,17 @@ void KeyManager::SetKey(S256KeyType id, Key256 key, u64 field1, u64 field2) { } bool KeyManager::KeyFileExists(bool title) { - const std::string hactool_keys_dir = Common::FS::GetHactoolConfigurationPath(); - const std::string yuzu_keys_dir = Common::FS::GetUserPath(Common::FS::UserPath::KeysDir); + const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir); + if (title) { - return Common::FS::Exists(hactool_keys_dir + DIR_SEP + "title.keys") || - Common::FS::Exists(yuzu_keys_dir + DIR_SEP + "title.keys"); + return Common::FS::Exists(yuzu_keys_dir / "title.keys"); } if (Settings::values.use_dev_keys) { - return Common::FS::Exists(hactool_keys_dir + DIR_SEP + "dev.keys") || - Common::FS::Exists(yuzu_keys_dir + DIR_SEP + "dev.keys"); + return Common::FS::Exists(yuzu_keys_dir / "dev.keys"); } - return Common::FS::Exists(hactool_keys_dir + DIR_SEP + "prod.keys") || - Common::FS::Exists(yuzu_keys_dir + DIR_SEP + "prod.keys"); + return Common::FS::Exists(yuzu_keys_dir / "prod.keys"); } void KeyManager::DeriveSDSeedLazy() { @@ -1115,15 +1122,21 @@ void KeyManager::PopulateTickets() { return; } - const Common::FS::IOFile save1(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir) + - "/system/save/80000000000000e1", - "rb+"); - const Common::FS::IOFile save2(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir) + - "/system/save/80000000000000e2", - "rb+"); + const auto system_save_e1_path = + Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/80000000000000e1"; + + const Common::FS::IOFile save_e1{system_save_e1_path, Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile}; + + const auto system_save_e2_path = + Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/80000000000000e2"; + + const Common::FS::IOFile save_e2{system_save_e2_path, Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile}; + + const auto blob2 = GetTicketblob(save_e2); + auto res = GetTicketblob(save_e1); - const auto blob2 = GetTicketblob(save2); - auto res = GetTicketblob(save1); const auto idx = res.size(); res.insert(res.end(), blob2.begin(), blob2.end()); diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index 0a7220286..e771625e1 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include #include @@ -283,9 +284,8 @@ private: std::array eticket_extended_kek{}; bool dev_mode; - void LoadFromFile(const std::string& filename, bool is_title_keys); - void AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2, - const std::string& filename, bool title); + void LoadFromFile(const std::filesystem::path& file_path, bool is_title_keys); + template void WriteKeyToFile(KeyCategory category, std::string_view keyname, const std::array& key); -- cgit v1.2.3