|
wired
libc-free QUIC/HTTP3 SDK in C for x86_64-linux
|
RFC 9001 4 / 4.1.2, RFC 8446 4 / 4.4.4, RFC 9000 7: server-side handshake orchestrator, the symmetric peer of quic_client. More...
#include "common/bytes/span/span.h"#include "common/platform/sys/syscall.h"#include "tls/handshake/core/sdrv/sdrv.h"#include "tls/handshake/roles/srvfin/complete.h"#include "tls/keys/kuswitch/twogen.h"#include "transport/conn/loop/crecv/collect.h"#include "transport/io/socket/io/udp.h"Go to the source code of this file.
Data Structures | |
| struct | wired_server |
| Server-side handshake orchestrator state, initialized by wired_server_init. More... | |
| struct | wired_server_init_in |
| server_priv_x25519/server_pub_x25519 are the static ECDHE pair; cert_seed is the ECDSA P-256 signing scalar (big-endian). More... | |
Macros | |
| #define | WIRED_SERVER_FLIGHT_MAX 2048 |
| Capacity of a server flight buffer in octets. | |
| #define | WIRED_SERVER_TRANSCRIPT_MAX 16384 |
| Capacity of the raw handshake transcript buffer in octets: ClientHello + ServerHello + the server Handshake flight, sized past quic-interop-runner's deliberately inflated 9-cert amplificationlimit chain (~10KB flight) with headroom. | |
| #define | WIRED_SERVER_DATAGRAM_MAX 1500 |
| Capacity of one received UDP datagram in octets. | |
Enumerations | |
| enum | { WIRED_SERVER_HS_INITIAL = 0 , WIRED_SERVER_HS_CH_RECVD , WIRED_SERVER_HS_FLIGHT_SENT , WIRED_SERVER_HS_CONFIRMED } |
| Handshake phases of the orchestrator (wired_server.phase). More... | |
Functions | |
| void | wired_server_init (wired_server *s, const wired_server_init_in *in) |
| Initialize the orchestrator with the server key material. | |
| int | wired_server_set_cids (wired_server *s, quic_span odcid, quic_span iscid) |
| RFC 9000 7.3: record the DCID of the client's first Initial (the ODCID the server echoes) and the server's source connection id (ISCID) so the EncryptedExtensions transport parameters carry the real connection ids. | |
| void | wired_server_set_limits (wired_server *s, u64 max_data, u64 max_streams_bidi, u64 max_datagram_frame_size) |
| Override the advertised transport-parameter limits (RFC 9000 18.2); a zero field keeps its built-in default. | |
| void | wired_server_set_keylog_path (wired_server *s, const char *path) |
| Set the NSS key log file path (SSLKEYLOGFILE format); 0 disables (the default). | |
| int | wired_server_recv_initial (wired_server *s, const u8 *ch_msg, usz ch_len) |
| RFC 8446 4.4.1: fold a received ClientHello (TLS handshake message bytes) into the transcript, recording ClientHello.random (bytes [4,36) of ch_msg: legacy_version(2) precedes it, RFC 8446 4.1.2) for later keylog lines. | |
| int | wired_server_build_flight (wired_server *s, const u8 *server_random, const quic_sdrv_flight_out *out) |
| RFC 8446 4.4 / RFC 9001 4: build the server flight (ServerHello into out->sh, EncryptedExtensions||Certificate||CertificateVerify||Finished into out->hs) and derive the Handshake key. | |
| int | wired_server_feed (wired_server *s, const u8 *crypto_payload, usz len) |
| RFC 8446 4.4.4 / RFC 9001 4.1.2: drive the handshake with one received Handshake-packet CRYPTO payload (socket-free injection). | |
| int | wired_server_handshake_done (wired_server *s, quic_obuf *out) |
| RFC 9001 4.1.2 / RFC 9000 19.20: write the HANDSHAKE_DONE frame, at most once and only after confirmation. | |
| int | wired_server_is_confirmed (const wired_server *s) |
| 1 once the client Finished verified and the handshake is confirmed. | |
| int | wired_server_resumption_secret (const wired_server *s, u8 out[32]) |
| RFC 8446 4.6.1/7.1: resumption_master_secret = Derive-Secret(Master Secret, "res master", ClientHello..client Finished) – the secret a NewSessionTicket must actually carry (RFC 8446 4.6.1: "The ticket itself
is an opaque label... the PSK associated with the ticket is computed as...
resumption_master_secret"). | |
| int | wired_server_listen (wired_server *s, u16 port) |
| Open a UDP socket bound to port and wait for the ClientHello. | |
| int | wired_server_pump (wired_server *s) |
| One receive iteration: pull a datagram off the socket and feed it. | |
| int | wired_server_run_handshake (wired_server *s, int max_iterations) |
| Pump until confirmed or max_iterations is reached (bounded so a silent or hostile peer cannot wedge the server). | |
| void | wired_server_close (wired_server *s) |
| Close the UDP socket. | |
RFC 9001 4 / 4.1.2, RFC 8446 4 / 4.4.4, RFC 9000 7: server-side handshake orchestrator, the symmetric peer of quic_client.
Drives the verified parts (sdrv folds the ClientHello and emits the server flight; srvfin verifies the client Finished and, only on success, advances to Master, installs the 1-RTT key set and confirms) to handshake confirmation and HANDSHAKE_DONE.
All policy lives in those layers; the server wires them and gates 1-RTT promotion on a verified client Finished. The data path (wired_server_feed) is socket-free so it can be driven by buffer injection without a socket; only wired_server_pump enters the kernel via io/udp.
| #define WIRED_SERVER_TRANSCRIPT_MAX 16384 |
Capacity of the raw handshake transcript buffer in octets: ClientHello + ServerHello + the server Handshake flight, sized past quic-interop-runner's deliberately inflated 9-cert amplificationlimit chain (~10KB flight) with headroom.
A truncated transcript silently desyncs srv_verify_finished's hash from the client's real one, so every client Finished fails and the server goes silent (RFC 8446 4.4.1/4.4.4).
| anonymous enum |
Handshake phases of the orchestrator (wired_server.phase).
| int wired_server_build_flight | ( | wired_server * | s, |
| const u8 * | server_random, | ||
| const quic_sdrv_flight_out * | out ) |
RFC 8446 4.4 / RFC 9001 4: build the server flight (ServerHello into out->sh, EncryptedExtensions||Certificate||CertificateVerify||Finished into out->hs) and derive the Handshake key.
Only valid after the ClientHello was received. Advances CH_RECVD -> FLIGHT_SENT.
| s | the orchestrator to advance |
| server_random | the ServerHello.random, 32 bytes |
| out | receives the ServerHello and the Handshake-level flight |
| void wired_server_close | ( | wired_server * | s | ) |
Close the UDP socket.
| s | the orchestrator whose socket to close |
| int wired_server_feed | ( | wired_server * | s, |
| const u8 * | crypto_payload, | ||
| usz | len ) |
RFC 8446 4.4.4 / RFC 9001 4.1.2: drive the handshake with one received Handshake-packet CRYPTO payload (socket-free injection).
Reassembles the client Finished, verifies its verify_data, and ONLY on a match advances to Master, installs the 1-RTT key set and confirms (CH_RECVD/FLIGHT_SENT -> CONFIRMED). A forged Finished promotes nothing.
| s | the orchestrator to advance |
| crypto_payload | one Handshake-packet CRYPTO payload |
| len | length of crypto_payload in octets |
| int wired_server_handshake_done | ( | wired_server * | s, |
| quic_obuf * | out ) |
RFC 9001 4.1.2 / RFC 9000 19.20: write the HANDSHAKE_DONE frame, at most once and only after confirmation.
| s | the orchestrator to emit from |
| out | receives the HANDSHAKE_DONE frame |
| void wired_server_init | ( | wired_server * | s, |
| const wired_server_init_in * | in ) |
Initialize the orchestrator with the server key material.
No socket is opened.
| s | the orchestrator to initialize |
| in | the server key material |
| int wired_server_is_confirmed | ( | const wired_server * | s | ) |
1 once the client Finished verified and the handshake is confirmed.
| s | the orchestrator to inspect |
| int wired_server_listen | ( | wired_server * | s, |
| u16 | port ) |
Open a UDP socket bound to port and wait for the ClientHello.
| s | the orchestrator that will own the socket |
| port | UDP port to bind |
| int wired_server_pump | ( | wired_server * | s | ) |
One receive iteration: pull a datagram off the socket and feed it.
| s | the orchestrator to pump |
| int wired_server_recv_initial | ( | wired_server * | s, |
| const u8 * | ch_msg, | ||
| usz | ch_len ) |
RFC 8446 4.4.1: fold a received ClientHello (TLS handshake message bytes) into the transcript, recording ClientHello.random (bytes [4,36) of ch_msg: legacy_version(2) precedes it, RFC 8446 4.1.2) for later keylog lines.
Advances INITIAL -> CH_RECVD.
| s | the orchestrator to advance |
| ch_msg | the ClientHello handshake message bytes |
| ch_len | length of ch_msg in octets |
| int wired_server_resumption_secret | ( | const wired_server * | s, |
| u8 | out[32] ) |
RFC 8446 4.6.1/7.1: resumption_master_secret = Derive-Secret(Master Secret, "res master", ClientHello..client Finished) – the secret a NewSessionTicket must actually carry (RFC 8446 4.6.1: "The ticket itself is an opaque label... the PSK associated with the ticket is computed as... resumption_master_secret").
Only meaningful once wired_server_is_ confirmed (the client Finished must have verified first); returns 0 (leaving out untouched) before that.
| s | the confirmed orchestrator to derive from |
| out | receives the 32-byte resumption_master_secret |
| int wired_server_run_handshake | ( | wired_server * | s, |
| int | max_iterations ) |
Pump until confirmed or max_iterations is reached (bounded so a silent or hostile peer cannot wedge the server).
| s | the orchestrator to pump |
| max_iterations | upper bound on receive iterations |
| int wired_server_set_cids | ( | wired_server * | s, |
| quic_span | odcid, | ||
| quic_span | iscid ) |
RFC 9000 7.3: record the DCID of the client's first Initial (the ODCID the server echoes) and the server's source connection id (ISCID) so the EncryptedExtensions transport parameters carry the real connection ids.
Must be called before build_flight.
| s | the orchestrator to record on |
| odcid | the DCID of the client's first Initial |
| iscid | the server's source connection id |
| void wired_server_set_keylog_path | ( | wired_server * | s, |
| const char * | path ) |
Set the NSS key log file path (SSLKEYLOGFILE format); 0 disables (the default).
When set, wired_server_feed appends a CLIENT_HANDSHAKE_TRAFFIC_ SECRET line once the client Finished verifies.
| s | the orchestrator to configure |
| path | NUL-terminated key log file path, or 0 to disable |
| void wired_server_set_limits | ( | wired_server * | s, |
| u64 | max_data, | ||
| u64 | max_streams_bidi, | ||
| u64 | max_datagram_frame_size ) |
Override the advertised transport-parameter limits (RFC 9000 18.2); a zero field keeps its built-in default.
Call before the flight is built.
| s | the server |
| max_data | initial_max_data in bytes (0 = default) |
| max_streams_bidi | initial_max_streams_bidi (0 = default) |
| max_datagram_frame_size | max_datagram_frame_size (RFC 9221 3), 0 = not advertised (no default: opt in once DATAGRAM delivery is wired) |