This PR adds Server Name Indication (SNI) support to the TLS server handshake on the zig-0.15.x branch.#29
Closed
pomelio wants to merge 1 commit into
Closed
This PR adds Server Name Indication (SNI) support to the TLS server handshake on the zig-0.15.x branch.#29pomelio wants to merge 1 commit into
zig-0.15.x branch.#29pomelio wants to merge 1 commit into
Conversation
Add SNI-based certificate selection to server handshake on `zig-0.15.x`
**PR Description**
This PR adds Server Name Indication (SNI) support to the TLS server
handshake on the `zig-0.15.x` branch.
The server now parses the `server_name` extension from `ClientHello`,
stores the requested hostname in handshake state, and allows callers to
select a certificate dynamically through a new `Options.sni_auth`
callback. If the callback does not return a certificate, the existing
`auth` field remains the default fallback.
- Added `Options.sni_auth` for dynamic certificate selection.
- Added server-side handshake state for the parsed SNI hostname.
- Implemented parsing for the `server_name` TLS extension in
`ClientHello`.
- Switched certificate emission in the server flight from fixed
`opt.auth` to the resolved handshake auth.
- Deferred signature scheme validation until after certificate
selection, so validation is performed against the actual certificate
chosen for the handshake.
- Added tests for:
- existing `ClientHello` parsing behavior
- SNI parsing and SNI-driven certificate selection
Before this change, the server always used a single certificate from
`auth`, regardless of the hostname requested by the client. That
prevented serving multiple TLS hostnames from the same listener.
This PR enables virtual hosting scenarios while keeping the existing API
behavior intact for callers that only provide `auth`.
New server option:
```zig
sni_auth: ?SniAuth = null
```
With:
```zig
pub const SniAuth = struct {
ctx: *anyopaque,
selectFn: *const fn (ctx: *anyopaque, server_name: ?[]const u8)
?*CertKeyPair,
};
```
Behavior:
- `selectFn` is called after parsing SNI from `ClientHello`
- if it returns a certificate, that certificate is used
- if it returns `null`, the handshake falls back to `auth`
This change is backward compatible:
- existing users of `auth` continue to work unchanged
- `sni_auth` is optional
Validated locally with:
```sh
zig fmt --check src/handshake_server.zig
zig test src/handshake_server.zig
```
Relevant SNI tests pass, including the new SNI-specific handshake
parsing test.
Note: the `zig test src/handshake_server.zig` run later crashes in an
existing unrelated client-side test (`handshake_client.test.handshake
verify server finished message`), after the new handshake server tests
have already passed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add SNI-based certificate selection to server handshake on
zig-0.15.xPR Description
This PR adds Server Name Indication (SNI) support to the TLS server handshake on the
zig-0.15.xbranch.The server now parses the
server_nameextension fromClientHello, stores the requested hostname in handshake state, and allows callers to select a certificate dynamically through a newOptions.sni_authcallback. If the callback does not return a certificate, the existingauthfield remains the default fallback.Options.sni_authfor dynamic certificate selection.server_nameTLS extension inClientHello.opt.authto the resolved handshake auth.ClientHelloparsing behaviorBefore this change, the server always used a single certificate from
auth, regardless of the hostname requested by the client. That prevented serving multiple TLS hostnames from the same listener.This PR enables virtual hosting scenarios while keeping the existing API behavior intact for callers that only provide
auth.New server option:
With:
Behavior:
selectFnis called after parsing SNI fromClientHellonull, the handshake falls back toauthThis change is backward compatible:
authcontinue to work unchangedsni_authis optionalValidated locally with:
zig fmt --check src/handshake_server.zig zig test src/handshake_server.zigRelevant SNI tests pass, including the new SNI-specific handshake parsing test.
Note: the
zig test src/handshake_server.zigrun later crashes in an existing unrelated client-side test (handshake_client.test.handshake verify server finished message), after the new handshake server tests have already passed.