Skip to content

Commit

Permalink
Fix MacOS bundle error
Browse files Browse the repository at this point in the history
  • Loading branch information
melonedo committed Mar 11, 2024
1 parent 68294f0 commit eb3f389
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 4 deletions.
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub fn main() !void {
var client = HttpClient{ .allocator = allocator };
defer client.deinit();
const url = "https://bing.com";
const url = "https://httpbin.org";
const uri = try std.Uri.parse(url);
var headers = std.http.Headers{ .allocator = allocator };
Expand Down
4 changes: 2 additions & 2 deletions src/crypto/Bundle.zig
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ pub fn rescan(cb: *Bundle, gpa: Allocator) RescanError!void {
}
}

const rescanMac = std.crypto.Certificate.Bundle.rescan;
const RescanMacError = std.crypto.Certificate.Bundle.RescanError;
const rescanMac = @import("Bundle/macos.zig").rescanMac;
const RescanMacError = @import("Bundle/macos.zig").RescanMacError;

const RescanLinuxError = AddCertsFromFilePathError || AddCertsFromDirPathError;

Expand Down
114 changes: 114 additions & 0 deletions src/crypto/Bundle/macos.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
const std = @import("std");
const assert = std.debug.assert;
const fs = std.fs;
const mem = std.mem;
const Allocator = std.mem.Allocator;
const Bundle = @import("../Bundle.zig");

pub const RescanMacError = Allocator.Error || fs.File.OpenError || fs.File.ReadError || fs.File.SeekError || Bundle.ParseCertError || error{EndOfStream};

pub fn rescanMac(cb: *Bundle, gpa: Allocator) RescanMacError!void {
cb.bytes.clearRetainingCapacity();
cb.map.clearRetainingCapacity();

const file = try fs.openFileAbsolute("/System/Library/Keychains/SystemRootCertificates.keychain", .{});
defer file.close();

const bytes = try file.readToEndAlloc(gpa, std.math.maxInt(u32));
defer gpa.free(bytes);

var stream = std.io.fixedBufferStream(bytes);
const reader = stream.reader();

const db_header = try reader.readStructBig(ApplDbHeader);
assert(mem.eql(u8, "kych", &@as([4]u8, @bitCast(db_header.signature))));

try stream.seekTo(db_header.schema_offset);

const db_schema = try reader.readStructBig(ApplDbSchema);

var table_list = try gpa.alloc(u32, db_schema.table_count);
defer gpa.free(table_list);

var table_idx: u32 = 0;
while (table_idx < table_list.len) : (table_idx += 1) {
table_list[table_idx] = try reader.readIntBig(u32);
}

const now_sec = std.time.timestamp();

for (table_list) |table_offset| {
try stream.seekTo(db_header.schema_offset + table_offset);

const table_header = try reader.readStructBig(TableHeader);

if (@as(std.os.darwin.cssm.DB_RECORDTYPE, @enumFromInt(table_header.table_id)) != .X509_CERTIFICATE) {
continue;
}

var record_list = try gpa.alloc(u32, table_header.record_count);
defer gpa.free(record_list);

var record_idx: u32 = 0;
while (record_idx < record_list.len) : (record_idx += 1) {
record_list[record_idx] = try reader.readIntBig(u32);
}

for (record_list) |record_offset| {
try stream.seekTo(db_header.schema_offset + table_offset + record_offset);

const cert_header = try reader.readStructBig(X509CertHeader);

try cb.bytes.ensureUnusedCapacity(gpa, cert_header.cert_size);

const cert_start = @as(u32, @intCast(cb.bytes.items.len));
const dest_buf = cb.bytes.allocatedSlice()[cert_start..];
cb.bytes.items.len += try reader.readAtLeast(dest_buf, cert_header.cert_size);

try cb.parseCert(gpa, cert_start, now_sec);
}
}

cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len);
}

const ApplDbHeader = extern struct {
signature: @Vector(4, u8),
version: u32,
header_size: u32,
schema_offset: u32,
auth_offset: u32,
};

const ApplDbSchema = extern struct {
schema_size: u32,
table_count: u32,
};

const TableHeader = extern struct {
table_size: u32,
table_id: u32,
record_count: u32,
records: u32,
indexes_offset: u32,
free_list_head: u32,
record_numbers_count: u32,
};

const X509CertHeader = extern struct {
record_size: u32,
record_number: u32,
unknown1: u32,
unknown2: u32,
cert_size: u32,
unknown3: u32,
cert_type: u32,
cert_encoding: u32,
print_name: u32,
alias: u32,
subject: u32,
issuer: u32,
serial_number: u32,
subject_key_identifier: u32,
public_key_hash: u32,
};
2 changes: 1 addition & 1 deletion src/example.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub fn main() !void {
var client = HttpClient{ .allocator = allocator };
defer client.deinit();

const url = "https://bing.com";
const url = "https://httpbin.org";

const uri = try std.Uri.parse(url);
var headers = std.http.Headers{ .allocator = allocator };
Expand Down

0 comments on commit eb3f389

Please sign in to comment.