From 9ec8439bb9c6fa330d23ffd299d716afece81d56 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Thu, 25 Aug 2016 19:47:46 -0700 Subject: Store SHA256 as hash2 in files2 for CodeDirectory. --- ldid.cpp | 88 +++++++++++++++++++++++++++++++++++++++++++++++++--------------- ldid.hpp | 2 +- 2 files changed, 69 insertions(+), 21 deletions(-) diff --git a/ldid.cpp b/ldid.cpp index 9fb3056..88ae5f1 100644 --- a/ldid.cpp +++ b/ldid.cpp @@ -51,20 +51,36 @@ #ifdef __APPLE__ #include + #define LDID_SHA1_DIGEST_LENGTH CC_SHA1_DIGEST_LENGTH #define LDID_SHA1 CC_SHA1 #define LDID_SHA1_CTX CC_SHA1_CTX #define LDID_SHA1_Init CC_SHA1_Init #define LDID_SHA1_Update CC_SHA1_Update #define LDID_SHA1_Final CC_SHA1_Final + +#define LDID_SHA256_DIGEST_LENGTH CC_SHA256_DIGEST_LENGTH +#define LDID_SHA256 CC_SHA256 +#define LDID_SHA256_CTX CC_SHA256_CTX +#define LDID_SHA256_Init CC_SHA256_Init +#define LDID_SHA256_Update CC_SHA256_Update +#define LDID_SHA256_Final CC_SHA256_Final #else #include + #define LDID_SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH #define LDID_SHA1 SHA1 #define LDID_SHA1_CTX SHA_CTX #define LDID_SHA1_Init SHA1_Init #define LDID_SHA1_Update SHA1_Update #define LDID_SHA1_Final SHA1_Final + +#define LDID_SHA256_DIGEST_LENGTH SHA256_DIGEST_LENGTH +#define LDID_SHA256 SHA256 +#define LDID_SHA256_CTX SHA256_CTX +#define LDID_SHA256_Init SHA256_Init +#define LDID_SHA256_Update SHA256_Update +#define LDID_SHA256_Final SHA256_Final #endif #ifndef LDID_NOPLIST @@ -1333,27 +1349,48 @@ class NullBuffer : } }; +class Hash { + public: + bool ready_; + char sha1_[LDID_SHA1_DIGEST_LENGTH]; + char sha256_[LDID_SHA256_DIGEST_LENGTH]; + + Hash() : + ready_(false) + { + } + + operator std::vector() const { + return {sha1_, sha1_ + sizeof(sha1_)}; + } +}; + class HashBuffer : public std::streambuf { private: - std::vector &hash_; - LDID_SHA1_CTX context_; + Hash &hash_; + + LDID_SHA1_CTX sha1_; + LDID_SHA256_CTX sha256_; public: - HashBuffer(std::vector &hash) : + HashBuffer(Hash &hash) : hash_(hash) { - LDID_SHA1_Init(&context_); + LDID_SHA1_Init(&sha1_); + LDID_SHA256_Init(&sha256_); } ~HashBuffer() { - hash_.resize(LDID_SHA1_DIGEST_LENGTH); - LDID_SHA1_Final(reinterpret_cast(hash_.data()), &context_); + LDID_SHA1_Final(reinterpret_cast(hash_.sha1_), &sha1_); + LDID_SHA256_Final(reinterpret_cast(hash_.sha256_), &sha256_); + hash_.ready_ = true; } virtual std::streamsize xsputn(const char_type *data, std::streamsize size) { - LDID_SHA1_Update(&context_, data, size); + LDID_SHA1_Update(&sha1_, data, size); + LDID_SHA256_Update(&sha256_, data, size); return size; } @@ -1373,7 +1410,7 @@ class HashProxy : std::streambuf &buffer_; public: - HashProxy(std::vector &hash, std::streambuf &buffer) : + HashProxy(Hash &hash, std::streambuf &buffer) : HashBuffer(hash), buffer_(buffer) { @@ -1930,7 +1967,7 @@ struct RuleCode { }; #ifndef LDID_NOPLIST -static void Sign(const uint8_t *prefix, size_t size, std::streambuf &buffer, std::vector &hash, std::streambuf &save, const std::string &identifier, const std::string &entitlements, const std::string &requirement, const std::string &key, const Slots &slots) { +static void Sign(const uint8_t *prefix, size_t size, std::streambuf &buffer, Hash &hash, std::streambuf &save, const std::string &identifier, const std::string &entitlements, const std::string &requirement, const std::string &key, const Slots &slots) { // XXX: this is a miserable fail std::stringbuf temp; put(temp, prefix, size); @@ -1941,7 +1978,7 @@ static void Sign(const uint8_t *prefix, size_t size, std::streambuf &buffer, std Sign(data.data(), data.size(), proxy, identifier, entitlements, requirement, key, slots); } -std::string Bundle(const std::string &root, Folder &folder, const std::string &key, std::map> &remote, const std::string &entitlements, const std::string &requirement) { +std::string Bundle(const std::string &root, Folder &folder, const std::string &key, std::map &remote, const std::string &entitlements, const std::string &requirement) { std::string executable; std::string identifier; @@ -1994,7 +2031,7 @@ std::string Bundle(const std::string &root, Folder &folder, const std::string &k rules2.insert(Rule{20, NoMode, "^version\\.plist$"}); } - std::map> local; + std::map local; static Expression nested("^PlugIns/[^/]*\\.appex/Info\\.plist$"); @@ -2012,7 +2049,7 @@ std::string Bundle(const std::string &root, Folder &folder, const std::string &k return; auto &hash(local[name]); - if (!hash.empty()) + if (hash.ready_) return; code(fun([&](std::streambuf &data, std::streambuf &save) { @@ -2045,7 +2082,7 @@ std::string Bundle(const std::string &root, Folder &folder, const std::string &k copy(data, proxy); })); - _assert(hash.size() == LDID_SHA1_DIGEST_LENGTH); + _assert(hash.ready_); })); auto plist(plist_new_dict()); @@ -2058,15 +2095,22 @@ std::string Bundle(const std::string &root, Folder &folder, const std::string &k for (const auto &rule : version.second) rule.Compile(); + bool old(&version.second == &rules1); + for (const auto &hash : local) for (const auto &rule : version.second) if (rule(hash.first)) { - if (rule.mode_ == NoMode) - plist_dict_set_item(files, hash.first.c_str(), plist_new_data(hash.second.data(), hash.second.size())); - else if (rule.mode_ == OptionalMode) { + if (rule.mode_ == NestedMode) { + // XXX: implement + } else if (rule.mode_ == NoMode && old) + plist_dict_set_item(files, hash.first.c_str(), plist_new_data(hash.second.sha1_, sizeof(hash.second.sha1_))); + else if (rule.mode_ != OmitMode) { auto entry(plist_new_dict()); - plist_dict_set_item(entry, "hash", plist_new_data(hash.second.data(), hash.second.size())); - plist_dict_set_item(entry, "optional", plist_new_bool(true)); + plist_dict_set_item(entry, "hash", plist_new_data(hash.second.sha1_, sizeof(hash.second.sha1_))); + if (!old) + plist_dict_set_item(entry, "hash2", plist_new_data(hash.second.sha256_, sizeof(hash.second.sha256_))); + if (rule.mode_ == OptionalMode) + plist_dict_set_item(entry, "optional", plist_new_bool(true)); plist_dict_set_item(files, hash.first.c_str(), entry); } @@ -2136,6 +2180,11 @@ std::string Bundle(const std::string &root, Folder &folder, const std::string &k return executable; } + +std::string Bundle(const std::string &root, Folder &folder, const std::string &key, const std::string &entitlements, const std::string &requirement) { + std::map hashes; + return Bundle(root, folder, key, hashes, entitlements, requirement); +} #endif #endif @@ -2311,8 +2360,7 @@ int main(int argc, char *argv[]) { #ifndef LDID_NOPLIST _assert(!flag_r); ldid::DiskFolder folder(path); - std::map> hashes; - path += "/" + Bundle("", folder, key, hashes, entitlements, requirement); + path += "/" + Bundle("", folder, key, entitlements, requirement); #else _assert(false); #endif diff --git a/ldid.hpp b/ldid.hpp index 3ca939c..0257ff2 100644 --- a/ldid.hpp +++ b/ldid.hpp @@ -139,7 +139,7 @@ class UnionFolder : } }; -std::string Bundle(const std::string &root, Folder &folder, const std::string &key, std::map> &remote, const std::string &entitlements, const std::string &requirement); +std::string Bundle(const std::string &root, Folder &folder, const std::string &key, const std::string &entitlements, const std::string &requirement); typedef std::map> Slots; -- cgit v1.2.3-56-ge451