Support loading custom CAs (--ca-cert, --ca-path) - #2891
Conversation
e042e4c to
63d96c3
Compare
6ad0702 to
50c5977
Compare
--ca-cert, --ca-path)
| // Report back if no certificates loaded. | ||
| defer { | ||
| const num_of_certs = crypto.getCertCount(store); | ||
| if (num_of_certs == 0) { |
There was a problem hiding this comment.
If --ca-path is hash directory, this will incorrectly warn.
| } | ||
| } | ||
|
|
||
| load_custom_ca: switch (config.mode) { |
There was a problem hiding this comment.
In the end, did we decide that if --ca-path or -ca-cert was specified, we'd continue to load the system certs too?
There was a problem hiding this comment.
I think we didn't, loading only what's provided would probably be the desired behavior.
| .{ .name = "v8_flags_unsafe", .type = ?[]const u8 }, | ||
| .{ .name = "v8_max_heap_mb", .type = ?u32 }, | ||
| .{ .name = "ca_cert", .type = [:0]const u8, .multiple = true }, | ||
| .{ .name = "ca_path", .type = [:0]const u8, .multiple = true, .validator = caPathValidator }, |
There was a problem hiding this comment.
It's a bit inconsistent that a bad ca_path stops the app from starting, but a bad ca_cert only warns at a later time.
There was a problem hiding this comment.
Agreed. I think we can either try parsing ca_cert in Config and store or make both warn at a later time.
Parsing before creating the store requires us to store the X509 pointers in somewhere though; so, if we can add something like this to Config, we can distinguish internal representation and CLI expectation.
.{
.name = "ca_cert",
.type = .{
.cli = [:0]const u8,
.memory = *crypto.X509,
},
.multiple = true,
},Which would expect [:0]const u8 from CLI but prefer std.ArrayList(*crypto.X509) in internal store.
Or, we can just parse 2 times; one in Config and the other at X509 store creation time.
There was a problem hiding this comment.
We still have inconsistency here:
- invalid
ca-path: the process doesn't start - invalid
ca-cert: the process starts w/ a warning "Invalid CA cert" but idk if we loaded the system's cert or if we disabled tls validation.
I think we should stop in both cases.
There was a problem hiding this comment.
I think we should stop in both cases.
Agreed, will match the behavior of both.
| return error.InvalidArgument; | ||
| } | ||
|
|
||
| return list.append(allocator, dir); |
There was a problem hiding this comment.
in cli.zig, the documentation says that strings are "duped from argv". So I assume if they have to be duped there, it has to be duped here?
|
|
50c5977 to
e279307
Compare
| }, | ||
| .help => unreachable, | ||
| .version => {}, // Don't load custom CA for version command. | ||
| } |
There was a problem hiding this comment.
Move the switch into a Config's accessors instead keeping it in Network.
Somehting like caCerts and caCertDirs.
| comp: OPENSSL_sk_cmp_func, | ||
| }; | ||
| pub const _STACK = struct_stack_st; | ||
| pub extern fn sk_num(sk: [*c]const _STACK) usize; |
There was a problem hiding this comment.
Claude complaints about this use:
2. The sk_num binding is unmodified translate-c output and uses a deprecated symbol. (src/sys/libcrypto.zig:356-368, 395-404)
- struct_stack_st is declared but never dereferenced — only used as a @ptrCast target. It's a silent trap if someone later reads a field and the layout has drifted. Delete it.
- sk_X509_OBJECT_num is Zig-only but declared callconv(.c) with a pointless const sk = arg_sk;. Compare findDigest at the bottom of the same file for the hand-written style.
- sk_num is OPENSSL_DEPRECATED (stack.h:302). OPENSSL_sk_num (stack.h:257) is the supported name with the identical size_t signature, and returns 0 for NULL — so the whole thing is
three lines with no null check needed.
WDYT?
There was a problem hiding this comment.
I think we can do counting by ourselves, though there shouldn't be any deprecation notice on sk_num on BoringSSL.
| .{ .name = "v8_flags_unsafe", .type = ?[]const u8 }, | ||
| .{ .name = "v8_max_heap_mb", .type = ?u32 }, | ||
| .{ .name = "ca_cert", .type = [:0]const u8, .multiple = true }, | ||
| .{ .name = "ca_path", .type = [:0]const u8, .multiple = true, .validator = caPathValidator }, |
There was a problem hiding this comment.
We still have inconsistency here:
- invalid
ca-path: the process doesn't start - invalid
ca-cert: the process starts w/ a warning "Invalid CA cert" but idk if we loaded the system's cert or if we disabled tls validation.
I think we should stop in both cases.
e279307 to
3e8a0e1
Compare
ec80029 to
efc0c26
Compare
* bind `X509_STORE_get0_objects`, * bind `sk_num`, * bind `sk_X509_OBJECT_num`, * add `getCertCount` helper.
Unifies how we report empty stores by checking directly on `X509_STORE`.
BoringSSL is fine with that still.
Storage fields can now be shared by CLI arguments; also having a different type for internal representation and CLI is also added.
Returns a pointer to `X509_STORE` if custom CA supplied, else null.
689248c to
a4ba95b
Compare
Addresses #2877, custom CA certs and directories can be provided via
--ca-certand--ca-path.In order to test, you can grab Mozilla CA store in PEM format from curl's website; then execute this: