]> git.cameronkatri.com Git - ldid.git/blobdiff - ldid.cpp
Use Apple's CommonCrypto for SHA-1 when __APPLE__.
[ldid.git] / ldid.cpp
index eb535fd82f808ce2a979469e15bf83a36f97673a..b863b359355c031234732ee03fb8a64cbb686011 100644 (file)
--- a/ldid.cpp
+++ b/ldid.cpp
 #include <openssl/pem.h>
 #include <openssl/pkcs7.h>
 #include <openssl/pkcs12.h>
+
+#ifdef __APPLE__
+#include <CommonCrypto/CommonDigest.h>
+#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 <openssl/sha.h>
+#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
 
 #include <plist/plist.h>
 
@@ -843,7 +860,7 @@ struct CodeDirectory {
 extern "C" uint32_t hash(uint8_t *k, uint32_t length, uint32_t initval);
 
 static void sha1(uint8_t *hash, const void *data, size_t size) {
-    SHA1(static_cast<const uint8_t *>(data), size, hash);
+    LDID_SHA1(static_cast<const uint8_t *>(data), size, hash);
 }
 
 struct CodesignAllocation {
@@ -1317,22 +1334,22 @@ class HashBuffer :
 {
   private:
     std::vector<char> &hash_;
-    SHA_CTX context_;
+    LDID_SHA1_CTX context_;
 
   public:
     HashBuffer(std::vector<char> &hash) :
         hash_(hash)
     {
-        SHA1_Init(&context_);
+        LDID_SHA1_Init(&context_);
     }
 
     ~HashBuffer() {
-        hash_.resize(SHA_DIGEST_LENGTH);
-        SHA1_Final(reinterpret_cast<uint8_t *>(hash_.data()), &context_);
+        hash_.resize(LDID_SHA1_DIGEST_LENGTH);
+        LDID_SHA1_Final(reinterpret_cast<uint8_t *>(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 +1472,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 +1505,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 +1519,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);
 
@@ -1661,6 +1678,41 @@ void SubFolder::Find(const std::string &path, const Functor<void (const std::str
     return parent_.Find(path_ + path, code);
 }
 
+UnionFolder::UnionFolder(Folder &parent) :
+    parent_(parent)
+{
+}
+
+void UnionFolder::Save(const std::string &path, const Functor<void (std::streambuf &)> &code) {
+    return parent_.Save(path, code);
+}
+
+bool UnionFolder::Open(const std::string &path, const Functor<void (std::streambuf &)> &code) {
+    auto file(files_.find(path));
+    if (file == files_.end())
+        return parent_.Open(path, code);
+
+    auto &data(file->second);
+    data.pubseekpos(0, std::ios::in);
+    code(data);
+    return true;
+}
+
+void UnionFolder::Find(const std::string &path, const Functor<void (const std::string &, const Functor<void (const Functor<void (std::streambuf &, std::streambuf &)> &)> &)> &code) {
+    parent_.Find(path, fun([&](const std::string &name, const Functor<void (const Functor<void (std::streambuf &, std::streambuf &)> &)> &save) {
+        if (files_.find(name) == files_.end())
+            code(name, save);
+    }));
+
+    for (auto &file : files_)
+        code(file.first, fun([&](const Functor<void (std::streambuf &, std::streambuf &)> &code) {
+            parent_.Save(file.first, fun([&](std::streambuf &save) {
+                file.second.pubseekpos(0, std::ios::in);
+                code(file.second, save);
+            }));
+        }));
+}
+
 static size_t copy(std::streambuf &source, std::streambuf &target) {
     size_t total(0);
     for (;;) {
@@ -1777,7 +1829,7 @@ struct RuleCode {
     }
 };
 
-std::string Bundle(const std::string &root, Folder &folder, const std::string &key, std::map<std::string, std::vector<char>> &remote) {
+std::string Bundle(const std::string &root, Folder &folder, const std::string &key, std::map<std::string, std::vector<char>> &remote, const std::string &entitlements) {
     std::string executable;
     std::string identifier;
 
@@ -1838,7 +1890,7 @@ std::string Bundle(const std::string &root, Folder &folder, const std::string &k
             return;
         auto bundle(root + Split(name).dir);
         SubFolder subfolder(folder, bundle);
-        Bundle(bundle, subfolder, key, local);
+        Bundle(bundle, subfolder, key, local, "");
     }));
 
     folder.Find("", fun([&](const std::string &name, const Functor<void (const Functor<void (std::streambuf &, std::streambuf &)> &)> &code) {
@@ -1854,7 +1906,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());
@@ -1943,7 +1995,7 @@ std::string Bundle(const std::string &root, Folder &folder, const std::string &k
             slots[3] = local.at(signature);
 
             HashProxy proxy(local[executable], save);
-            Sign(data.data(), data.size(), proxy, identifier, "", key, slots);
+            Sign(data.data(), data.size(), proxy, identifier, entitlements, key, slots);
         }));
     }));
 
@@ -2021,7 +2073,7 @@ int main(int argc, char *argv[]) {
                 unsigned number(strtoul(slot, &arge, 0));
                 _assert(arge == colon);
                 std::vector<char> &hash(slots[number]);
-                hash.resize(SHA_DIGEST_LENGTH);
+                hash.resize(LDID_SHA1_DIGEST_LENGTH);
                 sha1(reinterpret_cast<uint8_t *>(hash.data()), file.data(), file.size());
             } break;
 
@@ -2102,7 +2154,7 @@ int main(int argc, char *argv[]) {
             _assert(!flag_r);
             ldid::DiskFolder folder(path);
             std::map<std::string, std::vector<char>> hashes;
-            path += "/" + Bundle("", folder, key, hashes);
+            path += "/" + Bundle("", folder, key, hashes, entitlements);
         } else if (flag_S || flag_r) {
             Map input(path, O_RDONLY, PROT_READ, MAP_PRIVATE);
 
@@ -2199,7 +2251,7 @@ int main(int argc, char *argv[]) {
                         uint32_t begin = Swap(super->index[index].offset);
                         struct CodeDirectory *directory = reinterpret_cast<struct CodeDirectory *>(blob + begin);
 
-                        uint8_t (*hashes)[SHA_DIGEST_LENGTH] = reinterpret_cast<uint8_t (*)[SHA_DIGEST_LENGTH]>(blob + begin + Swap(directory->hashOffset));
+                        uint8_t (*hashes)[LDID_SHA1_DIGEST_LENGTH] = reinterpret_cast<uint8_t (*)[LDID_SHA1_DIGEST_LENGTH]>(blob + begin + Swap(directory->hashOffset));
                         uint32_t pages = Swap(directory->nCodeSlots);
 
                         if (pages != 1)