Commit 09560bc69a

Andrew Kelley <andrew@ziglang.org>
2023-01-16 22:59:41
clean up windows cert scanning
* keep helper functions out of the DLL bindings APIs * unify the logic for linux and windows certificate scanning with regards to error handling
1 parent 1f9fa82
Changed files (2)
lib
std
crypto
Certificate
os
windows
lib/std/crypto/Certificate/Bundle.zig
@@ -111,25 +111,29 @@ pub fn rescanWindows(cb: *Bundle, gpa: Allocator) !void {
     cb.bytes.clearRetainingCapacity();
     cb.map.clearRetainingCapacity();
 
-    const store = try os.windows.crypt32.certOpenSystemStoreW(null, &[4:0]u16{ 'R', 'O', 'O', 'T' });
-    defer os.windows.crypt32.certCloseStore(store, 0) catch unreachable;
-
-    var ctx = os.windows.crypt32.CertEnumCertificatesInStore(store, null);
-    while (ctx) |context| : (ctx = os.windows.crypt32.CertEnumCertificatesInStore(store, ctx)) {
-        var start = @intCast(u32, cb.bytes.items.len);
-        try cb.bytes.appendSlice(gpa, context.pbCertEncoded[0..context.cbCertEncoded]);
-        var parsed = Certificate.parse(.{
+    const w = std.os.windows;
+    const GetLastError = w.kernel32.GetLastError;
+    const root = [4:0]u16{ 'R', 'O', 'O', 'T' };
+    const store = w.crypt32.CertOpenSystemStoreW(null, &root) orelse switch (GetLastError()) {
+        .FILE_NOT_FOUND => return error.FileNotFound,
+        else => |err| return w.unexpectedError(err),
+    };
+    defer _ = w.crypt32.CertCloseStore(store, 0);
+
+    var ctx = w.crypt32.CertEnumCertificatesInStore(store, null);
+    while (ctx) |context| : (ctx = w.crypt32.CertEnumCertificatesInStore(store, ctx)) {
+        const decoded_start = @intCast(u32, cb.bytes.items.len);
+        const encoded_cert = context.pbCertEncoded[0..context.cbCertEncoded];
+        try cb.bytes.appendSlice(gpa, encoded_cert);
+        const parsed_cert = try Certificate.parse(.{
             .buffer = cb.bytes.items,
-            .index = start,
-        }) catch {
-            cb.bytes.items.len = start;
-            continue;
-        };
-        const gop = try cb.map.getOrPutContext(gpa, parsed.subject_slice, .{ .cb = cb });
+            .index = decoded_start,
+        });
+        const gop = try cb.map.getOrPutContext(gpa, parsed_cert.subject_slice, .{ .cb = cb });
         if (gop.found_existing) {
-            cb.bytes.items.len = start;
+            cb.bytes.items.len = decoded_start;
         } else {
-            gop.value_ptr.* = start;
+            gop.value_ptr.* = decoded_start;
         }
     }
     cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len);
@@ -250,7 +254,6 @@ pub fn parseCert(cb: *Bundle, gpa: Allocator, decoded_start: u32, now_sec: i64)
 const builtin = @import("builtin");
 const std = @import("../../std.zig");
 const assert = std.debug.assert;
-const os = std.os;
 const fs = std.fs;
 const mem = std.mem;
 const crypto = std.crypto;
lib/std/os/windows/crypt32.zig
@@ -5,7 +5,6 @@ const DWORD = windows.DWORD;
 const BYTE = windows.BYTE;
 const LPCWSTR = windows.LPCWSTR;
 const WINAPI = windows.WINAPI;
-const GetLastError = windows.kernel32.GetLastError;
 
 pub const CERT_INFO = *opaque {};
 pub const HCERTSTORE = *opaque {};
@@ -21,32 +20,11 @@ pub extern "crypt32" fn CertOpenSystemStoreW(
     _: ?*const anyopaque,
     szSubsystemProtocol: LPCWSTR,
 ) callconv(WINAPI) ?HCERTSTORE;
-pub fn certOpenSystemStoreW(
-    hProv: ?*const anyopaque,
-    szSubsystemProtocol: LPCWSTR,
-) !HCERTSTORE {
-    const value = CertOpenSystemStoreW(hProv, szSubsystemProtocol);
-    return if (value) |store|
-        store
-    else switch (GetLastError()) {
-        .FILE_NOT_FOUND => error.FileNotFound,
-        else => |err| windows.unexpectedError(err),
-    };
-}
 
 pub extern "crypt32" fn CertCloseStore(
     hCertStore: HCERTSTORE,
     dwFlags: DWORD,
 ) callconv(WINAPI) BOOL;
-pub fn certCloseStore(
-    hCertStore: HCERTSTORE,
-    dwFlags: DWORD,
-) !void {
-    const value = CertCloseStore(hCertStore, dwFlags);
-    if (value == 0) {
-        return windows.unexpectedError(GetLastError());
-    }
-}
 
 pub extern "crypt32" fn CertEnumCertificatesInStore(
     hCertStore: HCERTSTORE,