authorgravatar for dreilly1982@gmail.comDon <dreilly1982@gmail.com> 2025-01-31 16:02:42-06:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-02-09 04:16:56+01:00
logb3a11018ae1fe99190fb6fb7ae82a486c40f6f15
tree196b879b8e24f2410f35b748665f36c397e53fc9
parentea1ce2df9b20b5c91278eb0ed99a9cd0b0949e1a

Read System.keychain as well as SystemRootCertificates.keychain for MacOS CA Bundle


1 files changed, 44 insertions(+), 37 deletions(-)

lib/std/crypto/Certificate/Bundle/macos.zig+44-37
...@@ -11,61 +11,68 @@ pub fn rescanMac(cb: *Bundle, gpa: Allocator) RescanMacError!void {...@@ -11,61 +11,68 @@ pub fn rescanMac(cb: *Bundle, gpa: Allocator) RescanMacError!void {
11 cb.bytes.clearRetainingCapacity();11 cb.bytes.clearRetainingCapacity();
12 cb.map.clearRetainingCapacity();12 cb.map.clearRetainingCapacity();
1313
14 const file = try fs.openFileAbsolute("/System/Library/Keychains/SystemRootCertificates.keychain", .{});14 const keychainPaths = [2][]const u8{
15 defer file.close();15 "/System/Library/Keychains/SystemRootCertificates.keychain",
16 "/Library/Keychains/System.keychain",
17 };
1618
17 const bytes = try file.readToEndAlloc(gpa, std.math.maxInt(u32));19 for (keychainPaths) |keychainPath| {
18 defer gpa.free(bytes);20 const file = try fs.openFileAbsolute(keychainPath, .{});
21 defer file.close();
1922
20 var stream = std.io.fixedBufferStream(bytes);23 const bytes = try file.readToEndAlloc(gpa, std.math.maxInt(u32));
21 const reader = stream.reader();24 defer gpa.free(bytes);
2225
23 const db_header = try reader.readStructEndian(ApplDbHeader, .big);26 var stream = std.io.fixedBufferStream(bytes);
24 assert(mem.eql(u8, &db_header.signature, "kych"));27 const reader = stream.reader();
2528
26 try stream.seekTo(db_header.schema_offset);29 const db_header = try reader.readStructEndian(ApplDbHeader, .big);
30 assert(mem.eql(u8, &db_header.signature, "kych"));
2731
28 const db_schema = try reader.readStructEndian(ApplDbSchema, .big);32 try stream.seekTo(db_header.schema_offset);
2933
30 var table_list = try gpa.alloc(u32, db_schema.table_count);34 const db_schema = try reader.readStructEndian(ApplDbSchema, .big);
31 defer gpa.free(table_list);
3235
33 var table_idx: u32 = 0;36 var table_list = try gpa.alloc(u32, db_schema.table_count);
34 while (table_idx < table_list.len) : (table_idx += 1) {37 defer gpa.free(table_list);
35 table_list[table_idx] = try reader.readInt(u32, .big);
36 }
3738
38 const now_sec = std.time.timestamp();39 var table_idx: u32 = 0;
40 while (table_idx < table_list.len) : (table_idx += 1) {
41 table_list[table_idx] = try reader.readInt(u32, .big);
42 }
3943
40 for (table_list) |table_offset| {44 const now_sec = std.time.timestamp();
41 try stream.seekTo(db_header.schema_offset + table_offset);
4245
43 const table_header = try reader.readStructEndian(TableHeader, .big);46 for (table_list) |table_offset| {
47 try stream.seekTo(db_header.schema_offset + table_offset);
4448
45 if (@as(std.c.DB_RECORDTYPE, @enumFromInt(table_header.table_id)) != .X509_CERTIFICATE) {49 const table_header = try reader.readStructEndian(TableHeader, .big);
46 continue;
47 }
4850
49 var record_list = try gpa.alloc(u32, table_header.record_count);51 if (@as(std.c.DB_RECORDTYPE, @enumFromInt(table_header.table_id)) != .X509_CERTIFICATE) {
50 defer gpa.free(record_list);52 continue;
53 }
5154
52 var record_idx: u32 = 0;55 var record_list = try gpa.alloc(u32, table_header.record_count);
53 while (record_idx < record_list.len) : (record_idx += 1) {56 defer gpa.free(record_list);
54 record_list[record_idx] = try reader.readInt(u32, .big);57
55 }58 var record_idx: u32 = 0;
59 while (record_idx < record_list.len) : (record_idx += 1) {
60 record_list[record_idx] = try reader.readInt(u32, .big);
61 }
5662
57 for (record_list) |record_offset| {63 for (record_list) |record_offset| {
58 try stream.seekTo(db_header.schema_offset + table_offset + record_offset);64 try stream.seekTo(db_header.schema_offset + table_offset + record_offset);
5965
60 const cert_header = try reader.readStructEndian(X509CertHeader, .big);66 const cert_header = try reader.readStructEndian(X509CertHeader, .big);
6167
62 try cb.bytes.ensureUnusedCapacity(gpa, cert_header.cert_size);68 try cb.bytes.ensureUnusedCapacity(gpa, cert_header.cert_size);
6369
64 const cert_start = @as(u32, @intCast(cb.bytes.items.len));70 const cert_start = @as(u32, @intCast(cb.bytes.items.len));
65 const dest_buf = cb.bytes.allocatedSlice()[cert_start..];71 const dest_buf = cb.bytes.allocatedSlice()[cert_start..];
66 cb.bytes.items.len += try reader.readAtLeast(dest_buf, cert_header.cert_size);72 cb.bytes.items.len += try reader.readAtLeast(dest_buf, cert_header.cert_size);
6773
68 try cb.parseCert(gpa, cert_start, now_sec);74 try cb.parseCert(gpa, cert_start, now_sec);
75 }
69 }76 }
70 }77 }
7178