#pragma once #include "types.h" #include "KeyBag.h" #include "NcchProcess.h" #include #include #include #include #include #include #include namespace ctrtool { class CiaProcess { public: CiaProcess(); void setInputStream(const std::shared_ptr& input_stream); void setKeyBag(const ctrtool::KeyBag& key_bag); void setCliOutputMode(bool show_header_info); void setVerboseMode(bool verbose); void setVerifyMode(bool verify); void setCertExtractPath(const tc::io::Path& extract_path); void setTikExtractPath(const tc::io::Path& extract_path); void setTmdExtractPath(const tc::io::Path& extract_path); void setContentExtractPath(const tc::io::Path& extract_path); void setFooterExtractPath(const tc::io::Path& extract_path); void setContentIndex(size_t index); // ncch settings passed on void setRawMode(bool raw); void setPlainMode(bool plain); void setShowSyscallName(bool show_name); void setNcchRegionProcessOutputMode(NcchProcess::NcchRegion region, bool show_info, bool show_fs, const tc::Optional& bin_extract_path, const tc::Optional& fs_extract_path); void process(); private: std::string mModuleLabel; // input args std::shared_ptr mInputStream; ctrtool::KeyBag mKeyBag; bool mShowHeaderInfo; bool mVerbose; bool mVerify; tc::Optional mCertExtractPath; tc::Optional mTikExtractPath; tc::Optional mTmdExtractPath; tc::Optional mContentExtractPath; tc::Optional mFooterExtractPath; size_t mContentIndex; // process variables ntd::n3ds::CiaHeader mHeader; std::map> mIssuerSigner; std::map> mCertImportedIssuerSigner; std::vector mCertChain; std::vector mCertSigValid; ntd::n3ds::es::Ticket mTicket; ValidState mTicketSigValid; ntd::n3ds::es::TitleMetaData mTitleMetaData; ValidState mTitleMetaDataSigValid; tc::Optional mDecryptedTitleKey; bool mIsTwlTitle; ctrtool::NcchProcess mNcchProcess; std::shared_ptr mFsReader; struct CiaSectionInfo { int64_t offset; int64_t size; CiaSectionInfo() : offset(0), size(0) {} } mCertSizeInfo, mTikSizeInfo, mTmdSizeInfo, mContentSizeInfo, mFooterSizeInfo; struct ContentInfo { int64_t offset; int64_t size; uint32_t cid; uint16_t cindex; bool is_encrypted; bool is_hashed; std::array hash; int valid_state; ContentInfo() : offset(0), size(0), cid(0), cindex(0), is_encrypted(false), is_hashed(false), valid_state(ValidState::Unchecked) { memset(hash.data(), 0, hash.size()); } }; std::map mContentInfo; // helper methods void importIssuerProfiles(); void importHeader(); void verifyMetadata(); void verifyContent(); void printHeader(); void extractCia(); void copyStream(const std::shared_ptr& in, const std::shared_ptr& out); void processContent(); void createContentIv(std::array& content_iv, uint16_t index); bool isTwlTitle(uint64_t title_id); // string utils std::string getValidString(byte_t validstate); std::string getCiaTypeString(uint16_t type); std::string getFormatVersionString(uint16_t format_version); std::string getTruncatedBytesString(const byte_t* data, size_t len, bool do_not_truncate = false); std::string getSigTypeString(brd::es::ESSigType sig_type); std::string getCertificatePublicKeyTypeString(brd::es::ESCertPubKeyType public_key_type); std::string getTitleVersionString(uint16_t version); }; }