Making https request without verifying the certificate

Hello everyone. I have been trying for a day or so to make an https request without validating the certification how can i do that. Really appreciate the help

Is this while using std.http.Client?
This does TLS verification by default. This is based on the std.crypto.tls.Client which does validation and is not configurable. You can add certs to the ca_bundle and that would solve address your issue.

Huh, If you could provide an example i would be grateful because i have tried that and did not work the past few days i found that usually openssl required you to connect and provide the file descriptor for that connection in-order for it to perform the TLS hand shake so i did that below the example i used and it worked just fine if you can help we with even easier approach would be much better.

const std = @import("std");
const Io = std.Io;
const https = std.crypto.tls;
const http = std.http;
const net = Io.net;
const tls = std.crypto.tls;
const crypto = std.crypto;

pub fn main(init: std.process.Init) !void {
    const allocator = init.gpa;
    const io = init.io;

    const host_name = try net.HostName.init("fireflow.htb");
    const conn = try net.HostName.connect(host_name, io, 443, .{
        .mode = .stream,
        .protocol = .tcp,
    });
    defer conn.close(io);

    var read: [tls.max_ciphertext_record_len]u8 = undefined;
    var write: [tls.max_ciphertext_record_len]u8 = undefined;

    var reader = conn.reader(io, &read);
    var writer = conn.writer(io, &write);

    var orb: [tls.max_ciphertext_record_len]u8 = undefined;
    var owb: [tls.max_ciphertext_record_len]u8 = undefined;

    var entropy: [tls.Client.Options.entropy_len]u8 = undefined;
    try Io.randomSecure(io, &entropy);

    var client = try tls.Client.init(&reader.interface, &writer.interface, .{
        .ca = .no_verification,
        .host = .{ .explicit = "fireflow.htb" },
        .entropy = &entropy,
        .realtime_now = .now(io, .awake),
        .read_buffer = &orb,
        .write_buffer = &owb,
    });
    try client.writer.print("GET / HTTP/1.1\r\n", .{});
    try client.writer.print("Host: {s}\r\n", .{host_name.bytes});
    try client.writer.print("Connection: close\r\n", .{});

    try client.writer.print("\r\n", .{});
    try client.writer.flush();
    try client.output.flush();

    try Io.sleep(io, .fromSeconds(2), .awake);
    var total: usize = 0;
    var writer_from_buf: Io.Writer.Allocating = .init(allocator);
    defer writer_from_buf.deinit();

    while (true) {
        const n = client.reader.stream(&writer_from_buf.writer, .unlimited) catch |err| switch (err) {
            error.EndOfStream => {
                std.log.debug("Stream has ended", .{});
                break;
            },
            else => {
                std.log.err("{s}", .{@errorName(err)});
                return err;
            },
        };

        std.log.debug("Entering the loop n={d}", .{n});
        total += n;
    }
    std.log.info("total is {d}", .{total});
    std.debug.print("{s}\n", .{writer_from_buf.written()[0..total]});

    try client.end();
}

What I was suggesting is the following:

pub fn main(init: std.process.Init) !void {
    const io = init.io;
    const gpa = init.gpa;
    var ca_bundle = std.crypto.Certificate.Bundle.empty;
    try ca_bundle.rescan(gpa, io, .now(init.io, .real));
    // THIS LINE should add the cert and allow for verification
    try ca_bundle.addCertsFromFilePathAbsolute(gpa, io, .now(io, .real), "/path/to/fireflow.htb/cert");

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

    var body_writer = std.Io.Writer.Allocating.init(init.arena.allocator());
    const fireflow_url = try std.Uri.parse("https://fireflow.htb");
    const res = try client.fetch(.{
        .location = .{ .uri = fireflow_url },
        .method = .GET,
        .response_writer = &body_writer.writer,
        .extra_headers = &.{
            .{ .name = "Accept", .value = "text/html" },
        },
        .keep_alive = true,
    });
    std.debug.assert(res.status == .ok);

}

Your manual work around would be the only way to do it without adding or verifing the certificate.
My way still does verification, but because you add the certificate to the bundle, it passes.

I see what you mean. However i do not have the certificate for the site is there a way around that ?

You could download the certificate with a browser.

That issue is that the tool am working on it a web fuzzing tool like fuff its hard for me to ask the user ever time domain changes to download and provide the certificate

If that is the case, then you are probably going to have to go with the managed TLS connection like you already have. The current http.Client is not configurable for this use case.

Appreciate the help y’all thank you so much :heart:

I’ve noticed something similar: it would sure be nice to init an HTTP client with a reader and a writer, the server permits this.

I ended up using raw TCP in my project cause the http client wasn’t quite what I wanted with the new reader/writer ( to be fair I didn’t need http)