Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion SPEC/RFC5280_CHAIN_VALIDATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@ const tls_config = TlsConfig{

### Caveats

- `skip_cert_verify` defaults to `true` for backward compatibility
- `skip_cert_verify` defaults to `false`; callers must opt out explicitly for test-only/self-signed scenarios
- V1 certificates (no extensions) are accepted as CAs when no basicConstraints is present — this matches common practice but is less strict than RFC 5280's recommendation
- The interop client always uses `skip_cert_verify=true` since interop test peers use various self-signed certs
14 changes: 13 additions & 1 deletion src/quic/tls13.zig
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ pub const TlsConfig = struct {
private_key_bytes: []const u8, // Raw ECDSA P-256 private key (32 bytes)
alpn: []const []const u8,
server_name: ?[]const u8 = null, // SNI (client only)
skip_cert_verify: bool = true, // Skip X.509 chain + CertificateVerify validation
skip_cert_verify: bool = false, // Skip X.509 chain + CertificateVerify validation
ca_bundle: ?*Certificate.Bundle = null, // Caller-owned CA bundle for trust anchor verification
session_ticket: ?*const SessionTicket = null, // Stored ticket from previous connection (client)
ticket_key: ?[16]u8 = null, // AES-128-GCM key for encrypting/decrypting tickets (server)
Expand Down Expand Up @@ -2794,6 +2794,16 @@ test "buildServerHello: produces valid message" {
try std.testing.expectEqual(msg.len - 4, body_len);
}

test "TlsConfig defaults to certificate verification enabled" {
const config = TlsConfig{
.cert_chain_der = &.{},
.private_key_bytes = &.{},
.alpn = &.{},
};

try std.testing.expect(!config.skip_cert_verify);
}

test "loopback handshake: client and server complete" {
// Generate an ECDSA P-256 key pair for the server
const server_key_pair = EcdsaP256Sha256.KeyPair.generate();
Expand All @@ -2815,6 +2825,7 @@ test "loopback handshake: client and server complete" {
.private_key_bytes = &.{},
.alpn = &[_][]const u8{"h3"},
.server_name = "localhost",
.skip_cert_verify = true,
};

const server_tp = transport_params.TransportParams{
Expand Down Expand Up @@ -2961,6 +2972,7 @@ test "loopback PSK resumption: two handshakes with session ticket" {
.private_key_bytes = &.{},
.alpn = &[_][]const u8{"h3"},
.server_name = "localhost",
.skip_cert_verify = true,
};

const tp = transport_params.TransportParams{
Expand Down
Loading