authorgravatar for noob.tek.mb@gmail.comstar-tek-mb <noob.tek.mb@gmail.com> 2023-01-06 22:41:55+05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-17 00:08:42-07:00
log1f9fa822350ddf73fb7b3b9eb8f493ab64c935c8
tree6f125079acb184599bc57f68538493366ff86a6e
parentd56a65a8c4609a740eee43fd7073c2485c87c2c6

windows root certificate scanning


3 files changed, 85 insertions(+), 3 deletions(-)

lib/std/crypto/Certificate/Bundle.zig+30-3
......@@ -57,10 +57,8 @@ pub fn deinit(cb: *Bundle, gpa: Allocator) void {
5757pub fn rescan(cb: *Bundle, gpa: Allocator) !void {
5858 switch (builtin.os.tag) {
5959 .linux => return rescanLinux(cb, gpa),
60 .windows => {
61 // TODO
62 },
6360 .macos => return rescanMac(cb, gpa),
61 .windows => return rescanWindows(cb, gpa),
6462 else => {},
6563 }
6664}
......@@ -109,6 +107,34 @@ pub fn rescanLinux(cb: *Bundle, gpa: Allocator) !void {
109107 cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len);
110108}
111109
110pub fn rescanWindows(cb: *Bundle, gpa: Allocator) !void {
111 cb.bytes.clearRetainingCapacity();
112 cb.map.clearRetainingCapacity();
113
114 const store = try os.windows.crypt32.certOpenSystemStoreW(null, &[4:0]u16{ 'R', 'O', 'O', 'T' });
115 defer os.windows.crypt32.certCloseStore(store, 0) catch unreachable;
116
117 var ctx = os.windows.crypt32.CertEnumCertificatesInStore(store, null);
118 while (ctx) |context| : (ctx = os.windows.crypt32.CertEnumCertificatesInStore(store, ctx)) {
119 var start = @intCast(u32, cb.bytes.items.len);
120 try cb.bytes.appendSlice(gpa, context.pbCertEncoded[0..context.cbCertEncoded]);
121 var parsed = Certificate.parse(.{
122 .buffer = cb.bytes.items,
123 .index = start,
124 }) catch {
125 cb.bytes.items.len = start;
126 continue;
127 };
128 const gop = try cb.map.getOrPutContext(gpa, parsed.subject_slice, .{ .cb = cb });
129 if (gop.found_existing) {
130 cb.bytes.items.len = start;
131 } else {
132 gop.value_ptr.* = start;
133 }
134 }
135 cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len);
136}
137
112138pub fn addCertsFromDirPath(
113139 cb: *Bundle,
114140 gpa: Allocator,
......@@ -224,6 +250,7 @@ pub fn parseCert(cb: *Bundle, gpa: Allocator, decoded_start: u32, now_sec: i64)
224250const builtin = @import("builtin");
225251const std = @import("../../std.zig");
226252const assert = std.debug.assert;
253const os = std.os;
227254const fs = std.fs;
228255const mem = std.mem;
229256const crypto = std.crypto;
lib/std/os/windows.zig+1
......@@ -28,6 +28,7 @@ pub const user32 = @import("windows/user32.zig");
2828pub const ws2_32 = @import("windows/ws2_32.zig");
2929pub const gdi32 = @import("windows/gdi32.zig");
3030pub const winmm = @import("windows/winmm.zig");
31pub const crypt32 = @import("windows/crypt32.zig");
3132
3233pub const self_process_handle = @intToPtr(HANDLE, maxInt(usize));
3334
lib/std/os/windows/crypt32.zig created+54
......@@ -0,0 +1,54 @@
1const std = @import("../../std.zig");
2const windows = std.os.windows;
3const BOOL = windows.BOOL;
4const DWORD = windows.DWORD;
5const BYTE = windows.BYTE;
6const LPCWSTR = windows.LPCWSTR;
7const WINAPI = windows.WINAPI;
8const GetLastError = windows.kernel32.GetLastError;
9
10pub const CERT_INFO = *opaque {};
11pub const HCERTSTORE = *opaque {};
12pub const CERT_CONTEXT = extern struct {
13 dwCertEncodingType: DWORD,
14 pbCertEncoded: [*]BYTE,
15 cbCertEncoded: DWORD,
16 pCertInfo: CERT_INFO,
17 hCertStore: HCERTSTORE,
18};
19
20pub extern "crypt32" fn CertOpenSystemStoreW(
21 _: ?*const anyopaque,
22 szSubsystemProtocol: LPCWSTR,
23) callconv(WINAPI) ?HCERTSTORE;
24pub fn certOpenSystemStoreW(
25 hProv: ?*const anyopaque,
26 szSubsystemProtocol: LPCWSTR,
27) !HCERTSTORE {
28 const value = CertOpenSystemStoreW(hProv, szSubsystemProtocol);
29 return if (value) |store|
30 store
31 else switch (GetLastError()) {
32 .FILE_NOT_FOUND => error.FileNotFound,
33 else => |err| windows.unexpectedError(err),
34 };
35}
36
37pub extern "crypt32" fn CertCloseStore(
38 hCertStore: HCERTSTORE,
39 dwFlags: DWORD,
40) callconv(WINAPI) BOOL;
41pub fn certCloseStore(
42 hCertStore: HCERTSTORE,
43 dwFlags: DWORD,
44) !void {
45 const value = CertCloseStore(hCertStore, dwFlags);
46 if (value == 0) {
47 return windows.unexpectedError(GetLastError());
48 }
49}
50
51pub extern "crypt32" fn CertEnumCertificatesInStore(
52 hCertStore: HCERTSTORE,
53 pPrevCertContext: ?*CERT_CONTEXT,
54) callconv(WINAPI) ?*CERT_CONTEXT;