From 1f9fa822350ddf73fb7b3b9eb8f493ab64c935c8 Mon Sep 17 00:00:00 2001 From: star-tek-mb Date: Fri, 6 Jan 2023 22:41:55 +0500 Subject: windows root certificate scanning --- lib/std/crypto/Certificate/Bundle.zig | 33 +++++++++++++++++++-- lib/std/os/windows.zig | 1 + lib/std/os/windows/crypt32.zig | 54 +++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 lib/std/os/windows/crypt32.zig (limited to 'lib') diff --git a/lib/std/crypto/Certificate/Bundle.zig b/lib/std/crypto/Certificate/Bundle.zig index a8b3851b05..126d76261d 100644 --- a/lib/std/crypto/Certificate/Bundle.zig +++ b/lib/std/crypto/Certificate/Bundle.zig @@ -57,10 +57,8 @@ pub fn deinit(cb: *Bundle, gpa: Allocator) void { pub fn rescan(cb: *Bundle, gpa: Allocator) !void { switch (builtin.os.tag) { .linux => return rescanLinux(cb, gpa), - .windows => { - // TODO - }, .macos => return rescanMac(cb, gpa), + .windows => return rescanWindows(cb, gpa), else => {}, } } @@ -109,6 +107,34 @@ pub fn rescanLinux(cb: *Bundle, gpa: Allocator) !void { cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len); } +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(.{ + .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 }); + if (gop.found_existing) { + cb.bytes.items.len = start; + } else { + gop.value_ptr.* = start; + } + } + cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len); +} + pub fn addCertsFromDirPath( cb: *Bundle, gpa: Allocator, @@ -224,6 +250,7 @@ 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; diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index b38a7f73a7..44b42375e1 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -28,6 +28,7 @@ pub const user32 = @import("windows/user32.zig"); pub const ws2_32 = @import("windows/ws2_32.zig"); pub const gdi32 = @import("windows/gdi32.zig"); pub const winmm = @import("windows/winmm.zig"); +pub const crypt32 = @import("windows/crypt32.zig"); pub const self_process_handle = @intToPtr(HANDLE, maxInt(usize)); diff --git a/lib/std/os/windows/crypt32.zig b/lib/std/os/windows/crypt32.zig new file mode 100644 index 0000000000..b76b052bb5 --- /dev/null +++ b/lib/std/os/windows/crypt32.zig @@ -0,0 +1,54 @@ +const std = @import("../../std.zig"); +const windows = std.os.windows; +const BOOL = windows.BOOL; +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 {}; +pub const CERT_CONTEXT = extern struct { + dwCertEncodingType: DWORD, + pbCertEncoded: [*]BYTE, + cbCertEncoded: DWORD, + pCertInfo: CERT_INFO, + hCertStore: HCERTSTORE, +}; + +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, + pPrevCertContext: ?*CERT_CONTEXT, +) callconv(WINAPI) ?*CERT_CONTEXT; -- cgit v1.2.3 From 09560bc69a87f0540bd7a5a5c5e9e2a44db3a0cc Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 16 Jan 2023 14:59:41 -0700 Subject: 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 --- lib/std/crypto/Certificate/Bundle.zig | 37 +++++++++++++++++++---------------- lib/std/os/windows/crypt32.zig | 22 --------------------- 2 files changed, 20 insertions(+), 39 deletions(-) (limited to 'lib') diff --git a/lib/std/crypto/Certificate/Bundle.zig b/lib/std/crypto/Certificate/Bundle.zig index 126d76261d..94618c5ef8 100644 --- a/lib/std/crypto/Certificate/Bundle.zig +++ b/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; diff --git a/lib/std/os/windows/crypt32.zig b/lib/std/os/windows/crypt32.zig index b76b052bb5..9500d4b261 100644 --- a/lib/std/os/windows/crypt32.zig +++ b/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, -- cgit v1.2.3 From 62e3fdcf4faf6bdfdfd468d54b540eec74a8bdae Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 16 Jan 2023 16:30:28 -0800 Subject: std.crypto.Certificate: add more object ids --- lib/std/crypto/Certificate.zig | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'lib') diff --git a/lib/std/crypto/Certificate.zig b/lib/std/crypto/Certificate.zig index db984385bf..835232a36a 100644 --- a/lib/std/crypto/Certificate.zig +++ b/lib/std/crypto/Certificate.zig @@ -15,6 +15,8 @@ pub const Algorithm = enum { ecdsa_with_SHA256, ecdsa_with_SHA384, ecdsa_with_SHA512, + md2WithRSAEncryption, + md5WithRSAEncryption, pub const map = std.ComptimeStringMap(Algorithm, .{ .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05 }, .sha1WithRSAEncryption }, @@ -26,6 +28,8 @@ pub const Algorithm = enum { .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02 }, .ecdsa_with_SHA256 }, .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03 }, .ecdsa_with_SHA384 }, .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x04 }, .ecdsa_with_SHA512 }, + .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x02 }, .md2WithRSAEncryption }, + .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04 }, .md5WithRSAEncryption }, }); pub fn Hash(comptime algorithm: Algorithm) type { @@ -35,6 +39,8 @@ pub const Algorithm = enum { .ecdsa_with_SHA256, .sha256WithRSAEncryption => crypto.hash.sha2.Sha256, .ecdsa_with_SHA384, .sha384WithRSAEncryption => crypto.hash.sha2.Sha384, .ecdsa_with_SHA512, .sha512WithRSAEncryption => crypto.hash.sha2.Sha512, + .md2WithRSAEncryption => @compileError("unimplemented"), + .md5WithRSAEncryption => crypto.hash.Md5, }; } }; @@ -59,6 +65,7 @@ pub const Attribute = enum { organizationalUnitName, organizationIdentifier, pkcs9_emailAddress, + domainComponent, pub const map = std.ComptimeStringMap(Attribute, .{ .{ &[_]u8{ 0x55, 0x04, 0x03 }, .commonName }, @@ -70,6 +77,7 @@ pub const Attribute = enum { .{ &[_]u8{ 0x55, 0x04, 0x0B }, .organizationalUnitName }, .{ &[_]u8{ 0x55, 0x04, 0x61 }, .organizationIdentifier }, .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01 }, .pkcs9_emailAddress }, + .{ &[_]u8{ 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19 }, .domainComponent }, }); }; @@ -93,17 +101,40 @@ pub const ExtensionId = enum { crl_number, certificate_policies, authority_key_identifier, + msCertsrvCAVersion, + commonName, + ext_key_usage, + crl_distribution_points, + info_access, + entrustVersInfo, + enroll_certtype, + pe_logotype, + netscape_cert_type, + netscape_comment, pub const map = std.ComptimeStringMap(ExtensionId, .{ + .{ &[_]u8{ 0x55, 0x04, 0x03 }, .commonName }, + .{ &[_]u8{ 0x55, 0x1D, 0x01 }, .authority_key_identifier }, + .{ &[_]u8{ 0x55, 0x1D, 0x07 }, .subject_alt_name }, .{ &[_]u8{ 0x55, 0x1D, 0x0E }, .subject_key_identifier }, .{ &[_]u8{ 0x55, 0x1D, 0x0F }, .key_usage }, + .{ &[_]u8{ 0x55, 0x1D, 0x0A }, .basic_constraints }, .{ &[_]u8{ 0x55, 0x1D, 0x10 }, .private_key_usage_period }, .{ &[_]u8{ 0x55, 0x1D, 0x11 }, .subject_alt_name }, .{ &[_]u8{ 0x55, 0x1D, 0x12 }, .issuer_alt_name }, .{ &[_]u8{ 0x55, 0x1D, 0x13 }, .basic_constraints }, .{ &[_]u8{ 0x55, 0x1D, 0x14 }, .crl_number }, + .{ &[_]u8{ 0x55, 0x1D, 0x1F }, .crl_distribution_points }, .{ &[_]u8{ 0x55, 0x1D, 0x20 }, .certificate_policies }, .{ &[_]u8{ 0x55, 0x1D, 0x23 }, .authority_key_identifier }, + .{ &[_]u8{ 0x55, 0x1D, 0x25 }, .ext_key_usage }, + .{ &[_]u8{ 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01 }, .msCertsrvCAVersion }, + .{ &[_]u8{ 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01 }, .info_access }, + .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF6, 0x7D, 0x07, 0x41, 0x00 }, .entrustVersInfo }, + .{ &[_]u8{ 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02 }, .enroll_certtype }, + .{ &[_]u8{ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c }, .pe_logotype }, + .{ &[_]u8{ 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01 }, .netscape_cert_type }, + .{ &[_]u8{ 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d }, .netscape_comment }, }); }; @@ -238,6 +269,10 @@ pub const Parsed = struct { parsed_issuer.pub_key_algo, parsed_issuer.pubKey(), ), + + .md2WithRSAEncryption, .md5WithRSAEncryption => { + return error.CertificateSignatureAlgorithmUnsupported; + }, } } -- cgit v1.2.3 From 86308ba1e11a083f4ec91cf3b0e81a791892f851 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 16 Jan 2023 17:11:07 -0800 Subject: std.net.getAddressList: call WSAStartup on Windows --- lib/std/net.zig | 89 ++++++++++++++++++++++++++++++++++++++++++-------- lib/std/os/windows.zig | 33 ++++++++++--------- 2 files changed, 93 insertions(+), 29 deletions(-) (limited to 'lib') diff --git a/lib/std/net.zig b/lib/std/net.zig index da4cf30046..c4cee40a1d 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -746,7 +746,79 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*A const arena = result.arena.allocator(); errdefer result.deinit(); - if (builtin.target.os.tag == .windows or builtin.link_libc) { + if (builtin.target.os.tag == .windows) { + const name_c = try std.cstr.addNullByte(allocator, name); + defer allocator.free(name_c); + + const port_c = try std.fmt.allocPrintZ(allocator, "{}", .{port}); + defer allocator.free(port_c); + + const ws2_32 = os.windows.ws2_32; + const hints = os.addrinfo{ + .flags = ws2_32.AI.NUMERICSERV, + .family = os.AF.UNSPEC, + .socktype = os.SOCK.STREAM, + .protocol = os.IPPROTO.TCP, + .canonname = null, + .addr = null, + .addrlen = 0, + .next = null, + }; + var res: *os.addrinfo = undefined; + var first = true; + while (true) { + const rc = ws2_32.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res); + switch (@intToEnum(os.windows.ws2_32.WinsockError, @intCast(u16, rc))) { + @intToEnum(os.windows.ws2_32.WinsockError, 0) => break, + .WSATRY_AGAIN => return error.TemporaryNameServerFailure, + .WSANO_RECOVERY => return error.NameServerFailure, + .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported, + .WSA_NOT_ENOUGH_MEMORY => return error.OutOfMemory, + .WSAHOST_NOT_FOUND => return error.UnknownHostName, + .WSATYPE_NOT_FOUND => return error.ServiceUnavailable, + .WSAEINVAL => unreachable, + .WSAESOCKTNOSUPPORT => unreachable, + .WSANOTINITIALISED => { + if (!first) return error.Unexpected; + first = false; + try os.windows.callWSAStartup(); + continue; + }, + else => |err| return os.windows.unexpectedWSAError(err), + } + } + defer ws2_32.freeaddrinfo(res); + + const addr_count = blk: { + var count: usize = 0; + var it: ?*os.addrinfo = res; + while (it) |info| : (it = info.next) { + if (info.addr != null) { + count += 1; + } + } + break :blk count; + }; + result.addrs = try arena.alloc(Address, addr_count); + + var it: ?*os.addrinfo = res; + var i: usize = 0; + while (it) |info| : (it = info.next) { + const addr = info.addr orelse continue; + result.addrs[i] = Address.initPosix(@alignCast(4, addr)); + + if (info.canonname) |n| { + if (result.canon_name == null) { + result.canon_name = try arena.dupe(u8, mem.sliceTo(n, 0)); + } + } + i += 1; + } + + return result; + } + + if (builtin.link_libc) { const name_c = try std.cstr.addNullByte(allocator, name); defer allocator.free(name_c); @@ -765,19 +837,7 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*A .next = null, }; var res: *os.addrinfo = undefined; - const rc = sys.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res); - if (builtin.target.os.tag == .windows) switch (@intToEnum(os.windows.ws2_32.WinsockError, @intCast(u16, rc))) { - @intToEnum(os.windows.ws2_32.WinsockError, 0) => {}, - .WSATRY_AGAIN => return error.TemporaryNameServerFailure, - .WSANO_RECOVERY => return error.NameServerFailure, - .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported, - .WSA_NOT_ENOUGH_MEMORY => return error.OutOfMemory, - .WSAHOST_NOT_FOUND => return error.UnknownHostName, - .WSATYPE_NOT_FOUND => return error.ServiceUnavailable, - .WSAEINVAL => unreachable, - .WSAESOCKTNOSUPPORT => unreachable, - else => |err| return os.windows.unexpectedWSAError(err), - } else switch (rc) { + switch (sys.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res)) { @intToEnum(sys.EAI, 0) => {}, .ADDRFAMILY => return error.HostLacksNetworkAddresses, .AGAIN => return error.TemporaryNameServerFailure, @@ -824,6 +884,7 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*A return result; } + if (builtin.target.os.tag == .linux) { const flags = std.c.AI.NUMERICSERV; const family = os.AF.UNSPEC; diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 44b42375e1..a88b911bcb 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -1296,6 +1296,23 @@ pub fn WSACleanup() !void { var wsa_startup_mutex: std.Thread.Mutex = .{}; +pub fn callWSAStartup() !void { + wsa_startup_mutex.lock(); + defer wsa_startup_mutex.unlock(); + + // Here we could use a flag to prevent multiple threads to prevent + // multiple calls to WSAStartup, but it doesn't matter. We're globally + // leaking the resource intentionally, and the mutex already prevents + // data races within the WSAStartup function. + _ = WSAStartup(2, 2) catch |err| switch (err) { + error.SystemNotAvailable => return error.SystemResources, + error.VersionNotSupported => return error.Unexpected, + error.BlockingOperationInProgress => return error.Unexpected, + error.ProcessFdQuotaExceeded => return error.ProcessFdQuotaExceeded, + error.Unexpected => return error.Unexpected, + }; +} + /// Microsoft requires WSAStartup to be called to initialize, or else /// WSASocketW will return WSANOTINITIALISED. /// Since this is a standard library, we do not have the luxury of @@ -1338,21 +1355,7 @@ pub fn WSASocketW( .WSANOTINITIALISED => { if (!first) return error.Unexpected; first = false; - - wsa_startup_mutex.lock(); - defer wsa_startup_mutex.unlock(); - - // Here we could use a flag to prevent multiple threads to prevent - // multiple calls to WSAStartup, but it doesn't matter. We're globally - // leaking the resource intentionally, and the mutex already prevents - // data races within the WSAStartup function. - _ = WSAStartup(2, 2) catch |err| switch (err) { - error.SystemNotAvailable => return error.SystemResources, - error.VersionNotSupported => return error.Unexpected, - error.BlockingOperationInProgress => return error.Unexpected, - error.ProcessFdQuotaExceeded => return error.ProcessFdQuotaExceeded, - error.Unexpected => return error.Unexpected, - }; + try callWSAStartup(); continue; }, else => |err| return unexpectedWSAError(err), -- cgit v1.2.3 From 7623f3fad0f077d06ffef9eccdf77cb847e14f35 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 16 Jan 2023 21:47:15 -0700 Subject: std.crypto.Certificate: skip unknown attributes --- lib/std/crypto/Certificate.zig | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/std/crypto/Certificate.zig b/lib/std/crypto/Certificate.zig index 835232a36a..5785b40433 100644 --- a/lib/std/crypto/Certificate.zig +++ b/lib/std/crypto/Certificate.zig @@ -61,8 +61,10 @@ pub const Attribute = enum { countryName, localityName, stateOrProvinceName, + streetAddress, organizationName, organizationalUnitName, + postalCode, organizationIdentifier, pkcs9_emailAddress, domainComponent, @@ -73,8 +75,10 @@ pub const Attribute = enum { .{ &[_]u8{ 0x55, 0x04, 0x06 }, .countryName }, .{ &[_]u8{ 0x55, 0x04, 0x07 }, .localityName }, .{ &[_]u8{ 0x55, 0x04, 0x08 }, .stateOrProvinceName }, + .{ &[_]u8{ 0x55, 0x04, 0x09 }, .streetAddress }, .{ &[_]u8{ 0x55, 0x04, 0x0A }, .organizationName }, .{ &[_]u8{ 0x55, 0x04, 0x0B }, .organizationalUnitName }, + .{ &[_]u8{ 0x55, 0x04, 0x11 }, .postalCode }, .{ &[_]u8{ 0x55, 0x04, 0x61 }, .organizationIdentifier }, .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01 }, .pkcs9_emailAddress }, .{ &[_]u8{ 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19 }, .domainComponent }, @@ -389,13 +393,16 @@ pub fn parse(cert: Certificate) !Parsed { var atav_i = atav.slice.start; while (atav_i < atav.slice.end) { const ty_elem = try der.Element.parse(cert_bytes, atav_i); - const ty = try parseAttribute(cert_bytes, ty_elem); const val = try der.Element.parse(cert_bytes, ty_elem.slice.end); + atav_i = val.slice.end; + const ty = parseAttribute(cert_bytes, ty_elem) catch |err| switch (err) { + error.CertificateHasUnrecognizedObjectId => continue, + else => |e| return e, + }; switch (ty) { .commonName => common_name = val.slice, else => {}, } - atav_i = val.slice.end; } rdn_i = atav.slice.end; } -- cgit v1.2.3 From d35d086ae6206b706c9116d0376cabbdf6a25650 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 16 Jan 2023 22:19:49 -0700 Subject: std.crypto.Certificate: add more object id --- lib/std/crypto/Certificate.zig | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib') diff --git a/lib/std/crypto/Certificate.zig b/lib/std/crypto/Certificate.zig index 5785b40433..2916239f16 100644 --- a/lib/std/crypto/Certificate.zig +++ b/lib/std/crypto/Certificate.zig @@ -87,10 +87,12 @@ pub const Attribute = enum { pub const NamedCurve = enum { secp384r1, + secp521r1, X9_62_prime256v1, pub const map = std.ComptimeStringMap(NamedCurve, .{ .{ &[_]u8{ 0x2B, 0x81, 0x04, 0x00, 0x22 }, .secp384r1 }, + .{ &[_]u8{ 0x2B, 0x81, 0x04, 0x00, 0x23 }, .secp521r1 }, .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 }, .X9_62_prime256v1 }, }); }; @@ -754,6 +756,9 @@ fn verify_ecdsa( }; switch (sig_named_curve) { + .secp521r1 => { + return error.CertificateSignatureNamedCurveUnsupported; + }, .secp384r1 => { const P = crypto.ecc.P384; const Ecdsa = crypto.sign.ecdsa.Ecdsa(P, Hash); -- cgit v1.2.3