Skip to content

Commit

Permalink
allow use of std.crypto.Certificate.Bundle
Browse files Browse the repository at this point in the history
  • Loading branch information
Cloudef committed Dec 21, 2023
1 parent dea55fb commit b5529a8
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/easy.zig
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,16 @@ pub fn do(self: Self, req: anytype) !Response {
try checkCode(c.curl_easy_setopt(self.handle, c.CURLOPT_CUSTOMREQUEST, req.args.method.asString().ptr));
try checkCode(c.curl_easy_setopt(self.handle, c.CURLOPT_VERBOSE, req.getVerbose()));

const CaBundle = @import("main.zig").CaBundle;
if (CaBundle) |bundle| {
const blob = c.curl_blob {
.data = @constCast(bundle.ptr),
.len = bundle.len,
.flags = c.CURL_BLOB_NOCOPY,
};
try checkCode(c.curl_easy_setopt(self.handle, c.CURLOPT_CAINFO_BLOB, blob));
}

const body = try req.getBody(self.allocator);
defer if (body) |b| {
self.allocator.free(b);
Expand Down
34 changes: 34 additions & 0 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,38 @@ pub const Easy = @import("easy.zig");
pub usingnamespace Easy;
pub usingnamespace @import("c.zig");

pub var CaBundle: ?[]const u8 = null;

/// Not thread safe
/// Refreshes CaBundle for future requests
pub fn refresh_ca_bundle() !void {
if (CaBundle) |ptr| std.heap.c_allocator.free(ptr);
var bundle = std.crypto.Certificate.Bundle{};
defer bundle.deinit(std.heap.c_allocator);
try bundle.rescan(std.heap.c_allocator);
var pem = std.ArrayListUnmanaged(u8){};
const base64 = std.base64.standard.Encoder;
var iter = bundle.map.iterator();
while (iter.next()) |entry| {
const der = try std.crypto.Certificate.der.Element.parse(bundle.bytes.items, entry.value_ptr.*);
const cert = bundle.bytes.items[entry.value_ptr.*..der.slice.end];
const begin_marker = "-----BEGIN CERTIFICATE-----";
const end_marker = "\n-----END CERTIFICATE-----\n";
const encoded_sz = base64.calcSize(cert.len);
try pem.ensureTotalCapacity(std.heap.c_allocator, pem.items.len + encoded_sz);
var encoded = try std.heap.c_allocator.alloc(u8, encoded_sz);
defer std.heap.c_allocator.free(encoded);
_ = base64.encode(encoded[0..], cert);
try pem.appendSlice(std.heap.c_allocator, begin_marker);
for (encoded, 0..) |char, n| {
if (n % 64 == 0) try pem.append(std.heap.c_allocator, '\n');
try pem.append(std.heap.c_allocator, char);
}
try pem.appendSlice(std.heap.c_allocator, end_marker);
}
CaBundle = pem.items;
}

/// This function sets up the program environment that libcurl needs.
/// Since this function is not thread safe before libcurl 7.84.0, this function
/// must be called before the program calls any other function in libcurl.
Expand All @@ -17,6 +49,8 @@ pub fn global_init() !void {

/// This function releases resources acquired by curl_global_init.
pub fn global_deinit() void {
if (CaBundle) |bundle| std.heap.c_allocator.free(bundle);
CaBundle = null;
c.curl_global_cleanup();
}

Expand Down

0 comments on commit b5529a8

Please sign in to comment.