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 {
1111 cb.bytes.clearRetainingCapacity();
1212 cb.map.clearRetainingCapacity();
1313
14 const file = try fs.openFileAbsolute("/System/Library/Keychains/SystemRootCertificates.keychain", .{});
15 defer file.close();
14 const keychainPaths = [2][]const u8{
15 "/System/Library/Keychains/SystemRootCertificates.keychain",
16 "/Library/Keychains/System.keychain",
17 };
1618
17 const bytes = try file.readToEndAlloc(gpa, std.math.maxInt(u32));
18 defer gpa.free(bytes);
19 for (keychainPaths) |keychainPath| {
20 const file = try fs.openFileAbsolute(keychainPath, .{});
21 defer file.close();
1922
20 var stream = std.io.fixedBufferStream(bytes);
21 const reader = stream.reader();
23 const bytes = try file.readToEndAlloc(gpa, std.math.maxInt(u32));
24 defer gpa.free(bytes);
2225
23 const db_header = try reader.readStructEndian(ApplDbHeader, .big);
24 assert(mem.eql(u8, &db_header.signature, "kych"));
26 var stream = std.io.fixedBufferStream(bytes);
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);
31 defer gpa.free(table_list);
34 const db_schema = try reader.readStructEndian(ApplDbSchema, .big);
3235
33 var table_idx: u32 = 0;
34 while (table_idx < table_list.len) : (table_idx += 1) {
35 table_list[table_idx] = try reader.readInt(u32, .big);
36 }
36 var table_list = try gpa.alloc(u32, db_schema.table_count);
37 defer gpa.free(table_list);
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| {
41 try stream.seekTo(db_header.schema_offset + table_offset);
44 const now_sec = std.time.timestamp();
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) {
46 continue;
47 }
49 const table_header = try reader.readStructEndian(TableHeader, .big);
4850
49 var record_list = try gpa.alloc(u32, table_header.record_count);
50 defer gpa.free(record_list);
51 if (@as(std.c.DB_RECORDTYPE, @enumFromInt(table_header.table_id)) != .X509_CERTIFICATE) {
52 continue;
53 }
5154
52 var record_idx: u32 = 0;
53 while (record_idx < record_list.len) : (record_idx += 1) {
54 record_list[record_idx] = try reader.readInt(u32, .big);
55 }
55 var record_list = try gpa.alloc(u32, table_header.record_count);
56 defer gpa.free(record_list);
57
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| {
58 try stream.seekTo(db_header.schema_offset + table_offset + record_offset);
63 for (record_list) |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));
65 const dest_buf = cb.bytes.allocatedSlice()[cert_start..];
66 cb.bytes.items.len += try reader.readAtLeast(dest_buf, cert_header.cert_size);
70 const cert_start = @as(u32, @intCast(cb.bytes.items.len));
71 const dest_buf = cb.bytes.allocatedSlice()[cert_start..];
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 }
6976 }
7077 }
7178