aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Freeman (saurik) <saurik@saurik.com>2016-07-28 22:33:01 -0700
committerJay Freeman (saurik) <saurik@saurik.com>2016-07-28 22:33:01 -0700
commitb73d233368c114a6ece242efc265e2a45716653b (patch)
treeac97a8b545d115bbf2a1476be8dfcc5461eff6f2
parent7f5ad603882b1b27f5c1bfa2312c730e8938c760 (diff)
downloadldid-b73d233368c114a6ece242efc265e2a45716653b.tar.gz
ldid-b73d233368c114a6ece242efc265e2a45716653b.tar.zst
ldid-b73d233368c114a6ece242efc265e2a45716653b.zip
Embed team identifier of certificate in signature.
-rw-r--r--ldid.cpp52
1 files changed, 49 insertions, 3 deletions
diff --git a/ldid.cpp b/ldid.cpp
index 51c09dc..62b7498 100644
--- a/ldid.cpp
+++ b/ldid.cpp
@@ -810,6 +810,10 @@ struct CodeDirectory {
uint8_t spare1;
uint8_t pageSize;
uint32_t spare2;
+ uint32_t scatterOffset;
+ uint32_t teamIDOffset;
+ uint32_t spare3;
+ uint64_t codeLimit64;
} _packed;
#ifndef LDID_NOFLAGT
@@ -1426,6 +1430,26 @@ static void Commit(const std::string &path, const std::string &temp) {
namespace ldid {
void Sign(const void *idata, size_t isize, std::streambuf &output, const std::string &identifier, const std::string &entitlements, const std::string &key, const Slots &slots) {
+ std::string team;
+
+#ifndef LDID_NOSMIME
+ if (!key.empty()) {
+ std::stringbuf data;
+ Stuff stuff(key);
+ auto name(X509_get_subject_name(stuff));
+ _assert(name != NULL);
+ auto index(X509_NAME_get_index_by_NID(name, NID_organizationalUnitName, -1));
+ _assert(index >= 0);
+ auto next(X509_NAME_get_index_by_NID(name, NID_organizationalUnitName, index));
+ _assert(next == -1);
+ auto entry(X509_NAME_get_entry(name, index));
+ _assert(entry != NULL);
+ auto asn(X509_NAME_ENTRY_get_data(entry));
+ _assert(asn != NULL);
+ team.assign(reinterpret_cast<char *>(ASN1_STRING_data(asn)), ASN1_STRING_length(asn));
+ }
+#endif
+
Allocate(idata, isize, output, fun([&](const MachHeader &mach_header, size_t size) -> size_t {
size_t alloc(sizeof(struct SuperBlob));
@@ -1448,6 +1472,9 @@ void Sign(const void *idata, size_t isize, std::streambuf &output, const std::st
alloc += sizeof(struct CodeDirectory);
alloc += identifier.size() + 1;
+ if (!team.empty())
+ alloc += team.size() + 1;
+
if (!key.empty()) {
alloc += sizeof(struct BlobIndex);
alloc += sizeof(struct Blob);
@@ -1502,10 +1529,8 @@ void Sign(const void *idata, size_t isize, std::streambuf &output, const std::st
uint32_t normal((limit + PageSize_ - 1) / PageSize_);
CodeDirectory directory;
- directory.version = Swap(uint32_t(0x00020001));
+ directory.version = Swap(uint32_t(0x00020200));
directory.flags = Swap(uint32_t(0));
- 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);
@@ -1514,9 +1539,30 @@ void Sign(const void *idata, size_t isize, std::streambuf &output, const std::st
directory.spare1 = 0x00;
directory.pageSize = PageShift_;
directory.spare2 = Swap(uint32_t(0));
+ directory.scatterOffset = Swap(uint32_t(0));
+ directory.spare3 = Swap(uint32_t(0));
+ directory.codeLimit64 = Swap(uint64_t(0));
+
+ uint32_t offset(sizeof(Blob) + sizeof(CodeDirectory));
+
+ directory.identOffset = Swap(uint32_t(offset));
+ offset += identifier.size() + 1;
+
+ if (team.empty())
+ directory.teamIDOffset = Swap(uint32_t(0));
+ else {
+ directory.teamIDOffset = Swap(uint32_t(offset));
+ offset += team.size() + 1;
+ }
+
+ offset += LDID_SHA1_DIGEST_LENGTH * special;
+ directory.hashOffset = Swap(uint32_t(offset));
+ offset += LDID_SHA1_DIGEST_LENGTH * normal;
+
put(data, &directory, sizeof(directory));
put(data, identifier.c_str(), identifier.size() + 1);
+ put(data, team.c_str(), team.size() + 1);
uint8_t storage[special + normal][LDID_SHA1_DIGEST_LENGTH];
uint8_t (*hashes)[LDID_SHA1_DIGEST_LENGTH] = storage + special;