srctree

Gregory Mullen parent 58ecb1c8 328a7411
expose tls cipher suites config to init

inlinesplit
lib/std/crypto/tls/Client.zig added: 67, removed: 19, total 48
@@ -120,11 +120,51 @@ pub fn InitError(comptime Stream: type) type {
};
}
 
test "tls" {
const a = std.testing.allocator;
var client = std.http.Client{
.allocator = a,
};
defer client.deinit();
 
var arr = std.ArrayList(u8).init(a);
defer arr.deinit();
 
_ = try client.fetch(.{
.location = .{ .url = "https://ziglang.org/" },
.max_append_size = 200,
.response_storage = .{
.dynamic = &arr,
},
});
 
std.debug.print("host {s}\n", .{arr.items});
}
 
pub const TLSOptions = struct {
/// Certificate Bundle a value of null will disable certificate
/// verification. This is unlikely to be desired behavior. Specifying a ca
/// bundle is *strongly* recommended.
ca_bundle: Certificate.Bundle,
/// The FQDN of the host connection if set to null, no SNI extension will be
/// sent to the server.
host: []const u8,
/// The default, (and currently only supported) version is TLS v1.3
comptime minimum_version: tls.ProtocolVersion = .tls_1_3,
/// Override the default cipher suite list. Normally overriding is not
/// necessary and you should do so *only* if you fully understand the
/// implications of doing so.
comptime cipher_suites: []const u8 = default_cipher_suites,
};
 
/// Initiates a TLS handshake and establishes a TLSv1.3 session with `stream`, which
/// must conform to `StreamInterface`.
///
/// `host` is only borrowed during this function call.
pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) InitError(@TypeOf(stream))!Client {
pub fn init(stream: anytype, options: TLSOptions) InitError(@TypeOf(stream))!Client {
const ca_bundle = options.ca_bundle;
const host = options.host;
const cipher_suites = options.cipher_suites;
const host_len: u16 = @intCast(host.len);
 
var random_buffer: [128]u8 = undefined;
@@ -1430,22 +1470,27 @@ fn limitVecs(iovecs: []std.posix.iovec, len: usize) []std.posix.iovec {
/// aegis-256: 461 MiB/s
/// aes128-gcm: 138 MiB/s
/// aes256-gcm: 120 MiB/s
const cipher_suites = if (crypto.core.aes.has_hardware_support)
enum_array(tls.CipherSuite, &.{
.AEGIS_128L_SHA256,
.AEGIS_256_SHA512,
.AES_128_GCM_SHA256,
.AES_256_GCM_SHA384,
.CHACHA20_POLY1305_SHA256,
})
pub const hardware_supported_aes_cipher_suites = enum_array(tls.CipherSuite, &.{
.AEGIS_128L_SHA256,
.AEGIS_256_SHA512,
.AES_128_GCM_SHA256,
.AES_256_GCM_SHA384,
.CHACHA20_POLY1305_SHA256,
});
 
// Default suite is marked as pub
pub const default_cipher_suites = enum_array(tls.CipherSuite, &.{
.CHACHA20_POLY1305_SHA256,
.AEGIS_128L_SHA256,
.AEGIS_256_SHA512,
.AES_128_GCM_SHA256,
.AES_256_GCM_SHA384,
});
 
pub const performance_optimized_cipher_suites = if (crypto.core.aes.has_hardware_support)
hardware_supported_aes_cipher_suites
else
enum_array(tls.CipherSuite, &.{
.CHACHA20_POLY1305_SHA256,
.AEGIS_128L_SHA256,
.AEGIS_256_SHA512,
.AES_128_GCM_SHA256,
.AES_256_GCM_SHA384,
});
default_cipher_suites;
 
test {
_ = StreamInterface;
 
lib/std/http/Client.zig added: 67, removed: 19, total 48
@@ -1354,7 +1354,10 @@ pub fn connectTcp(client: *Client, host: []const u8, port: u16, protocol: Connec
conn.data.tls_client = try client.allocator.create(std.crypto.tls.Client);
errdefer client.allocator.destroy(conn.data.tls_client);
 
conn.data.tls_client.* = std.crypto.tls.Client.init(stream, client.ca_bundle, host) catch return error.TlsInitializationFailed;
conn.data.tls_client.* = std.crypto.tls.Client.init(stream, .{
.ca_bundle = client.ca_bundle,
.host = host,
}) catch return error.TlsInitializationFailed;
// This is appropriate for HTTPS because the HTTP headers contain
// the content length which is used to detect truncation attacks.
conn.data.tls_client.allow_truncation_attacks = true;