Commit d14cd59ef0

Jakub Konka <kubkon@jakubkonka.com>
2020-11-20 10:11:16
stage2 macho: move code signature logic into struct
1 parent 3ac8046
Changed files (2)
src/link/MachO/CodeSignature.zig
@@ -0,0 +1,59 @@
+const CodeSignature = @This();
+
+const std = @import("std");
+const assert = std.debug.assert;
+const log = std.log.scoped(.link);
+const macho = std.macho;
+const mem = std.mem;
+const testing = std.testing;
+const Allocator = mem.Allocator;
+
+// pub const Blob = union(enum) {
+//     Signature: struct{
+//         inner:
+//     }
+// };
+
+alloc: *Allocator,
+inner: macho.SuperBlob = .{
+    .magic = macho.CSMAGIC_EMBEDDED_SIGNATURE,
+    .length = @sizeOf(macho.SuperBlob),
+    .count = 0,
+},
+// blobs: std.ArrayList(Blob),
+
+pub fn init(alloc: *Allocator) CodeSignature {
+    return .{
+        .alloc = alloc,
+        // .indices = std.ArrayList(Blob).init(alloc),
+    };
+}
+
+pub fn calcAdhocSignature(self: *CodeSignature) !void {}
+
+pub fn size(self: CodeSignature) u32 {
+    return self.inner.length;
+}
+
+pub fn write(self: CodeSignature, buffer: []u8) void {
+    assert(buffer.len >= self.inner.length);
+    self.writeHeader(buffer);
+}
+
+pub fn deinit(self: *CodeSignature) void {}
+
+fn writeHeader(self: CodeSignature, buffer: []u8) void {
+    assert(buffer.len >= @sizeOf(macho.SuperBlob));
+    mem.writeIntBig(u32, buffer[0..4], self.inner.magic);
+    mem.writeIntBig(u32, buffer[4..8], self.inner.length);
+    mem.writeIntBig(u32, buffer[8..12], self.inner.count);
+}
+
+test "CodeSignature header" {
+    var code_sig = CodeSignature.init(testing.allocator);
+    defer code_sig.deinit();
+    var buffer: [@sizeOf(macho.SuperBlob)]u8 = undefined;
+    code_sig.writeHeader(buffer[0..]);
+    const expected = &[_]u8{ 0xfa, 0xde, 0x0c, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0 };
+    testing.expect(mem.eql(u8, expected[0..], buffer[0..]));
+}
src/link/MachO.zig
@@ -21,6 +21,7 @@ const Cache = @import("../Cache.zig");
 const target_util = @import("../target.zig");
 
 const Trie = @import("MachO/Trie.zig");
+const CodeSignature = @import("MachO/CodeSignature.zig");
 
 pub const base_tag: File.Tag = File.Tag.macho;
 
@@ -385,7 +386,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
                 self.libsystem_cmd_dirty = false;
             }
 
-            try self.codeSign();
+            try self.writecodeSignature();
         },
         .Obj => {},
         .Lib => return error.TODOImplementWritingLibFiles,
@@ -1751,60 +1752,20 @@ fn writeAllUndefSymbols(self: *MachO) !void {
     try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undef_symbols.items), off);
 }
 
-fn codeSign(self: *MachO) !void {
+fn writecodeSignature(self: *MachO) !void {
     const code_sig_cmd = &self.load_commands.items[self.code_signature_cmd_index.?].LinkeditData;
-    // TODO add actual code signing mechanism
-    var buffer: std.ArrayListUnmanaged(u8) = .{};
-    defer buffer.deinit(self.base.allocator);
-    // var super_blob = macho.SuperBlob{
-    //     .magic = macho.CSMAGIC_EMBEDDED_SIGNATURE,
-    //     .length = 0,
-    //     .count = 2,
-    // };
-    const length: u32 = @sizeOf(u32) * 12;
-    try buffer.ensureCapacity(self.base.allocator, length);
-    var buf: [@sizeOf(u32)]u8 = undefined;
-    mem.writeIntBig(u32, &buf, macho.CSMAGIC_EMBEDDED_SIGNATURE);
-    buffer.appendSliceAssumeCapacity(buf[0..]);
-    mem.writeIntBig(u32, &buf, length);
-    buffer.appendSliceAssumeCapacity(buf[0..]);
-    mem.writeIntBig(u32, &buf, 2);
-    buffer.appendSliceAssumeCapacity(buf[0..]);
-    // macho.BlobIndex{
-    //     .type = macho.CSSLOT_REQUIREMENTS,
-    //     .offset = offset,
-    // };
-    mem.writeIntBig(u32, &buf, macho.CSSLOT_REQUIREMENTS);
-    buffer.appendSliceAssumeCapacity(buf[0..]);
-    mem.writeIntBig(u32, &buf, 28);
-    buffer.appendSliceAssumeCapacity(buf[0..]);
-    // macho.BlobIndex{
-    //     .type = macho.CSSLOT_SIGNATURESLOT,
-    //     .offset = offset,
-    // };
-    mem.writeIntBig(u32, &buf, macho.CSSLOT_SIGNATURESLOT);
-    buffer.appendSliceAssumeCapacity(buf[0..]);
-    mem.writeIntBig(u32, &buf, 40);
-    buffer.appendSliceAssumeCapacity(buf[0..]);
-    // const requirements_blob = macho.GenericBlob{
-    //     .magic = macho.CSMAGIC_REQUIREMENTS,
-    //     .length = 0,
-    // };
-    mem.writeIntBig(u32, &buf, macho.CSMAGIC_REQUIREMENTS);
-    buffer.appendSliceAssumeCapacity(buf[0..]);
-    mem.writeIntBig(u32, &buf, @sizeOf(u32) * 3);
-    buffer.appendSliceAssumeCapacity(buf[0..]);
-    mem.writeIntBig(u32, &buf, 0);
-    buffer.appendSliceAssumeCapacity(buf[0..]);
-    // const signature_blob = macho.GenericBlob{
-    //     .magic = macho.CSSLOT_SIGNATURESLOT,
-    //     .length = 0,
-    // };
-    mem.writeIntBig(u32, &buf, macho.CSMAGIC_BLOBWRAPPER);
-    buffer.appendSliceAssumeCapacity(buf[0..]);
-    mem.writeIntBig(u32, &buf, @sizeOf(u32) * 2);
-    buffer.appendSliceAssumeCapacity(buf[0..]);
-    try self.base.file.?.pwriteAll(buffer.items[0..], code_sig_cmd.dataoff);
+
+    var code_sig = CodeSignature.init(self.base.allocator);
+    defer code_sig.deinit();
+
+    try code_sig.calcAdhocSignature();
+
+    var buffer = try self.base.allocator.alloc(u8, code_sig.size());
+    defer self.base.allocator.free(buffer);
+
+    code_sig.write(buffer);
+
+    try self.base.file.?.pwriteAll(buffer, code_sig_cmd.dataoff);
     try self.base.file.?.pwriteAll(&[_]u8{ 0 }, code_sig_cmd.dataoff + code_sig_cmd.datasize - 1);
 }