Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for verifying SSL certificates signed with X9_62_prime256v1 #14406

Closed
andrewrk opened this issue Jan 22, 2023 · 3 comments · Fixed by #14419
Closed

add support for verifying SSL certificates signed with X9_62_prime256v1 #14406

andrewrk opened this issue Jan 22, 2023 · 3 comments · Fixed by #14419
Labels
contributor friendly This issue is limited in scope and/or knowledge of Zig internals. enhancement Solving this issue will likely involve adding new logic or components to the codebase. standard library This issue involves writing Zig code for the standard library.
Milestone

Comments

@andrewrk
Copy link
Member

To reproduce the problem:

const std = @import("std");
const http = std.http;

pub fn main() !void {
    var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    const arena = arena_instance.allocator();
    const gpa = arena;

    const args = try std.process.argsAlloc(arena);

    var client: http.Client = .{
        .allocator = gpa,
    };
    try client.ca_bundle.rescan(gpa);
    defer client.deinit();

    const uri = try std.Uri.parse(args[1]);
    var req = try client.request(uri, .{}, .{});

    const stdout = if (args.len >= 3)
        try std.fs.cwd().createFile(args[2], .{})
    else
        std.io.getStdOut();

    var total: usize = 0;
    var buf: [20000]u8 = undefined;
    while (true) {
        const amt = try req.readAll(&buf);
        total += amt;
        if (amt == 0) break;
        try stdout.writeAll(buf[0..amt]);
    }
}
$ stage3/bin/zig build-exe test.zig 
$ ./test https://reveng.sourceforge.io/crc-catalogue/all.htm
error: CertificateSignatureNamedCurveUnsupported
/home/andy/dev/zig/lib/std/crypto/Certificate.zig:804:13: 0x3c098f in verify_ecdsa__anon_52270 (test)
            return error.CertificateSignatureNamedCurveUnsupported;
            ^
/home/andy/dev/zig/lib/std/crypto/Certificate.zig:271:28: 0x364a77 in verify (test)
            => |algorithm| return verify_ecdsa(
                           ^
/home/andy/dev/zig/lib/std/crypto/tls/Client.zig:470:37: 0x351ae8 in init__anon_6618 (test)
                                    try prev_cert.verify(subject, now_sec);
                                    ^
/home/andy/dev/zig/lib/std/http/Client.zig:860:31: 0x3698fe in connect (test)
            conn.tls_client = try std.crypto.tls.Client.init(conn.stream, client.ca_bundle, host);
                              ^
/home/andy/dev/zig/lib/std/http/Client.zig:893:23: 0x370165 in request (test)
        .connection = try client.connect(host, port, protocol),
                      ^
/home/andy/dev/zig/build-release/test.zig:18:15: 0x381220 in main (test)
    var req = try client.request(uri, .{}, .{});
              ^

switch (sig_named_curve) {
.secp521r1 => {
return error.CertificateSignatureNamedCurveUnsupported;
},
.secp384r1 => {
const P = crypto.ecc.P384;
const Ecdsa = crypto.sign.ecdsa.Ecdsa(P, Hash);
const sig = Ecdsa.Signature.fromDer(encoded_sig) catch |err| switch (err) {
error.InvalidEncoding => return error.CertificateSignatureInvalid,
};
const pub_key = Ecdsa.PublicKey.fromSec1(sec1_pub_key) catch |err| switch (err) {
error.InvalidEncoding => return error.CertificateSignatureInvalid,
error.NonCanonical => return error.CertificateSignatureInvalid,
error.NotSquare => return error.CertificateSignatureInvalid,
};
sig.verify(message, pub_key) catch |err| switch (err) {
error.IdentityElement => return error.CertificateSignatureInvalid,
error.NonCanonical => return error.CertificateSignatureInvalid,
error.SignatureVerificationFailed => return error.CertificateSignatureInvalid,
};
},
.X9_62_prime256v1 => {
return error.CertificateSignatureNamedCurveUnsupported;
},
}

cc @jedisct1 - I would welcome any hints you have about what algorithms to use for this - not sure which (if any) std.crypto APIs corresponds to this.

@andrewrk andrewrk added enhancement Solving this issue will likely involve adding new logic or components to the codebase. contributor friendly This issue is limited in scope and/or knowledge of Zig internals. standard library This issue involves writing Zig code for the standard library. labels Jan 22, 2023
@andrewrk andrewrk added this to the 0.11.0 milestone Jan 22, 2023
@nektro
Copy link
Contributor

nektro commented Jan 22, 2023

https://gist.github.com/tolpp/c5f831659b113b1e1f024ca5a8d8d427 says its:

ANSI X9.62 elliptic curve prime256v1 (aka secp256r1, NIST P-256), SHA512withECDSA

@nektro
Copy link
Contributor

nektro commented Jan 22, 2023

@jedisct1
Copy link
Contributor

Yes, this is just P256.

So, using the same code as .secp384r1 with ecc.P256 should work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contributor friendly This issue is limited in scope and/or knowledge of Zig internals. enhancement Solving this issue will likely involve adding new logic or components to the codebase. standard library This issue involves writing Zig code for the standard library.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants