X-Git-Url: https://git.saurik.com/ldid.git/blobdiff_plain/4d03333fd9a1e4bc0508e23054cb6b6442a87d68..f5db0fc2c3ba3137c5e8b76d577ccd58ae342a63:/ldid.cpp diff --git a/ldid.cpp b/ldid.cpp index 049338b..9619daf 100644 --- a/ldid.cpp +++ b/ldid.cpp @@ -42,13 +42,34 @@ #include #include +#ifndef LDID_NOSMIME #include #include #include #include +#endif + +#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 +#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 +#endif +#ifndef LDID_NOPLIST #include +#endif #include "ldid.hpp" @@ -57,11 +78,20 @@ #define _assert__(line) \ _assert___(line) +#ifdef __EXCEPTIONS #define _assert_(expr, format, ...) \ do if (!(expr)) { \ fprintf(stderr, "%s(%u): _assert(): " format "\n", __FILE__, __LINE__, ## __VA_ARGS__); \ throw __FILE__ "(" _assert__(__LINE__) "): _assert(" #expr ")"; \ } while (false) +#else +// XXX: this is not acceptable +#define _assert_(expr, format, ...) \ + do if (!(expr)) { \ + fprintf(stderr, "%s(%u): _assert(): " format "\n", __FILE__, __LINE__, ## __VA_ARGS__); \ + exit(-1); \ + } while (false) +#endif #define _assert(expr) \ _assert_(expr, "%s", #expr) @@ -840,10 +870,12 @@ struct CodeDirectory { uint32_t spare2; } _packed; +#ifndef LDID_NOFLAGT extern "C" uint32_t hash(uint8_t *k, uint32_t length, uint32_t initval); +#endif static void sha1(uint8_t *hash, const void *data, size_t size) { - SHA1(static_cast(data), size, hash); + LDID_SHA1(static_cast(data), size, hash); } struct CodesignAllocation { @@ -1185,6 +1217,7 @@ static size_t put(std::streambuf &output, uint32_t magic, const Blobs &blobs) { return offset; } +#ifndef LDID_NOSMIME class Buffer { private: BIO *bio_; @@ -1298,6 +1331,7 @@ class Signature { return value_; } }; +#endif class NullBuffer : public std::streambuf @@ -1317,22 +1351,22 @@ class HashBuffer : { private: std::vector &hash_; - SHA_CTX context_; + LDID_SHA1_CTX context_; public: HashBuffer(std::vector &hash) : hash_(hash) { - SHA1_Init(&context_); + LDID_SHA1_Init(&context_); } ~HashBuffer() { - hash_.resize(SHA_DIGEST_LENGTH); - SHA1_Final(reinterpret_cast(hash_.data()), &context_); + hash_.resize(LDID_SHA1_DIGEST_LENGTH); + LDID_SHA1_Final(reinterpret_cast(hash_.data()), &context_); } virtual std::streamsize xsputn(const char_type *data, std::streamsize size) { - SHA1_Update(&context_, data, size); + LDID_SHA1_Update(&context_, data, size); return size; } @@ -1455,7 +1489,7 @@ void Sign(const void *idata, size_t isize, std::streambuf &output, const std::st special = std::max(special, slot.first); uint32_t normal((size + PageSize_ - 1) / PageSize_); - alloc = Align(alloc + (special + normal) * SHA_DIGEST_LENGTH, 16); + alloc = Align(alloc + (special + normal) * LDID_SHA1_DIGEST_LENGTH, 16); return alloc; }), fun([&](std::streambuf &output, size_t limit, const std::string &overlap, const char *top) -> size_t { Blobs blobs; @@ -1488,12 +1522,12 @@ void Sign(const void *idata, size_t isize, std::streambuf &output, const std::st CodeDirectory directory; directory.version = Swap(uint32_t(0x00020001)); directory.flags = Swap(uint32_t(0)); - directory.hashOffset = Swap(uint32_t(sizeof(Blob) + sizeof(CodeDirectory) + identifier.size() + 1 + SHA_DIGEST_LENGTH * special)); + directory.hashOffset = Swap(uint32_t(sizeof(Blob) + sizeof(CodeDirectory) + identifier.size() + 1 + LDID_SHA1_DIGEST_LENGTH * special)); directory.identOffset = Swap(uint32_t(sizeof(Blob) + sizeof(CodeDirectory))); directory.nSpecialSlots = Swap(special); directory.codeLimit = Swap(uint32_t(limit)); directory.nCodeSlots = Swap(normal); - directory.hashSize = SHA_DIGEST_LENGTH; + directory.hashSize = LDID_SHA1_DIGEST_LENGTH; directory.hashType = CS_HASHTYPE_SHA1; directory.spare1 = 0x00; directory.pageSize = PageShift_; @@ -1502,8 +1536,8 @@ void Sign(const void *idata, size_t isize, std::streambuf &output, const std::st put(data, identifier.c_str(), identifier.size() + 1); - uint8_t storage[special + normal][SHA_DIGEST_LENGTH]; - uint8_t (*hashes)[SHA_DIGEST_LENGTH] = storage + special; + uint8_t storage[special + normal][LDID_SHA1_DIGEST_LENGTH]; + uint8_t (*hashes)[LDID_SHA1_DIGEST_LENGTH] = storage + special; memset(storage, 0, sizeof(*storage) * special); @@ -1528,6 +1562,7 @@ void Sign(const void *idata, size_t isize, std::streambuf &output, const std::st insert(blobs, CSSLOT_CODEDIRECTORY, CSMAGIC_CODEDIRECTORY, data); } +#ifndef LDID_NOSMIME if (!key.empty()) { std::stringbuf data; const std::string &sign(blobs[CSSLOT_CODEDIRECTORY]); @@ -1542,6 +1577,7 @@ void Sign(const void *idata, size_t isize, std::streambuf &output, const std::st insert(blobs, CSSLOT_SIGNATURESLOT, CSMAGIC_BLOBWRAPPER, data); } +#endif return put(output, CSMAGIC_EMBEDDED_SIGNATURE, blobs); })); @@ -1709,6 +1745,7 @@ static size_t copy(std::streambuf &source, std::streambuf &target) { return total; } +#ifndef LDID_NOPLIST static plist_t plist(const std::string &data) { plist_t plist(NULL); if (Starts(data, "bplist00")) @@ -1736,6 +1773,7 @@ static std::string plist_s(plist_t node) { _scope({ free(data); }); return data; } +#endif enum Mode { NoMode, @@ -1812,6 +1850,7 @@ struct RuleCode { } }; +#ifndef LDID_NOPLIST std::string Bundle(const std::string &root, Folder &folder, const std::string &key, std::map> &remote, const std::string &entitlements) { std::string executable; std::string identifier; @@ -1889,7 +1928,7 @@ std::string Bundle(const std::string &root, Folder &folder, const std::string &k copy(data, proxy); })); - _assert(hash.size() == SHA_DIGEST_LENGTH); + _assert(hash.size() == LDID_SHA1_DIGEST_LENGTH); })); auto plist(plist_new_dict()); @@ -1987,11 +2026,14 @@ std::string Bundle(const std::string &root, Folder &folder, const std::string &k return executable; } +#endif } int main(int argc, char *argv[]) { +#ifndef LDID_NOSMIME OpenSSL_add_all_algorithms(); +#endif union { uint16_t word; @@ -2003,7 +2045,9 @@ int main(int argc, char *argv[]) { bool flag_r(false); bool flag_e(false); +#ifndef LDID_NOFLAGT bool flag_T(false); +#endif bool flag_S(false); bool flag_s(false); @@ -2018,8 +2062,10 @@ int main(int argc, char *argv[]) { const char *flag_I(NULL); +#ifndef LDID_NOFLAGT bool timeh(false); uint32_t timev(0); +#endif Map entitlements; Map key; @@ -2056,7 +2102,7 @@ int main(int argc, char *argv[]) { unsigned number(strtoul(slot, &arge, 0)); _assert(arge == colon); std::vector &hash(slots[number]); - hash.resize(SHA_DIGEST_LENGTH); + hash.resize(LDID_SHA1_DIGEST_LENGTH); sha1(reinterpret_cast(hash.data()), file.data(), file.size()); } break; @@ -2099,6 +2145,7 @@ int main(int argc, char *argv[]) { key.open(argv[argi] + 2, O_RDONLY, PROT_READ, MAP_PRIVATE); break; +#ifndef LDID_NOFLAGT case 'T': { flag_T = true; if (argv[argi][2] == '-') @@ -2109,6 +2156,7 @@ int main(int argc, char *argv[]) { _assert(arge == argv[argi] + strlen(argv[argi])); } } break; +#endif case 'I': { flag_I = argv[argi] + 2; @@ -2134,10 +2182,14 @@ int main(int argc, char *argv[]) { _syscall(stat(path.c_str(), &info)); if (S_ISDIR(info.st_mode)) { +#ifndef LDID_NOPLIST _assert(!flag_r); ldid::DiskFolder folder(path); std::map> hashes; path += "/" + Bundle("", folder, key, hashes, entitlements); +#else + _assert(false); +#endif } else if (flag_S || flag_r) { Map input(path, O_RDONLY, PROT_READ, MAP_PRIVATE); @@ -2155,7 +2207,15 @@ int main(int argc, char *argv[]) { Commit(path, temp); } - Map mapping(path, flag_T || flag_s); + bool modify(false); +#ifndef LDID_NOFLAGT + if (flag_T) + modify = true; +#endif + if (flag_s) + modify = true; + + Map mapping(path, modify); FatHeader fat_header(mapping.data(), mapping.size()); _foreach (mach_header, fat_header.GetMachHeaders()) { @@ -2180,6 +2240,7 @@ int main(int argc, char *argv[]) { signature = reinterpret_cast(load_command); else if (cmd == LC_ENCRYPTION_INFO || cmd == LC_ENCRYPTION_INFO_64) encryption = reinterpret_cast(load_command); +#ifndef LDID_NOFLAGT else if (cmd == LC_ID_DYLIB) { volatile struct dylib_command *dylib_command(reinterpret_cast(load_command)); @@ -2196,6 +2257,7 @@ int main(int argc, char *argv[]) { dylib_command->dylib.timestamp = mach_header.Swap(timed); } } +#endif } if (flag_D) { @@ -2234,7 +2296,7 @@ int main(int argc, char *argv[]) { uint32_t begin = Swap(super->index[index].offset); struct CodeDirectory *directory = reinterpret_cast(blob + begin); - uint8_t (*hashes)[SHA_DIGEST_LENGTH] = reinterpret_cast(blob + begin + Swap(directory->hashOffset)); + uint8_t (*hashes)[LDID_SHA1_DIGEST_LENGTH] = reinterpret_cast(blob + begin + Swap(directory->hashOffset)); uint32_t pages = Swap(directory->nCodeSlots); if (pages != 1)