Line data Source code
1 : #ifndef HEADER_fd_src_waltz_quic_tls_fd_quic_tls_h 2 : #define HEADER_fd_src_waltz_quic_tls_fd_quic_tls_h 3 : 4 : #include "../fd_quic_common.h" 5 : #include "../fd_quic_enum.h" 6 : #include "../../tls/fd_tls.h" 7 : #include "../templ/fd_quic_transport_params.h" 8 : 9 : /* QUIC-TLS 10 : 11 : fd_quic_tls_new( mem, &cfg ) initializes caller-owned fd_quic_tls_t 12 : storage. cfg supplies a seeded CSPRNG, signer, certificate public 13 : key and callbacks. The RNG and signer context must outlive the object. 14 : 15 : fd_quic_tls_hs_new( hs_mem, quic_tls, context, is_server, 16 : &self_transport_params, now ) initializes a 17 : handshake in caller-owned storage. Clients send ClientHello on 18 : creation; servers wait for it. 19 : 20 : Reassemble CRYPTO input in hs->rx_hs_buf, set rx_sz and rx_enc_level, 21 : then call fd_quic_tls_process. See fd_quic_handle_crypto_frame for 22 : buffer offsets and encryption-level transitions. Send queued output 23 : using fd_quic_tls_get_hs_data / fd_quic_tls_pop_hs_data. 24 : 25 : fd_quic_tls_hs_delete and fd_quic_tls_delete do not free storage. */ 26 : 27 : /* each TLS handshake requires a number of fd_quic_tls_hs_data structures */ 28 405999 : #define FD_QUIC_TLS_HS_DATA_CNT 16u 29 : 30 : /* alignment of hs_data 31 : must be a power of 2 */ 32 42579 : #define FD_QUIC_TLS_HS_DATA_ALIGN 32u 33 : 34 : /* number of bytes allocated for queued handshake data 35 : must be a multiple of FD_QUIC_TLS_HS_DATA_ALIGN */ 36 85158 : #define FD_QUIC_TLS_HS_DATA_SZ (2048UL) 37 : 38 : /* callback function prototypes */ 39 : 40 : typedef void 41 : (* fd_quic_tls_cb_secret_t)( fd_quic_tls_hs_t * hs, 42 : void * context, 43 : fd_quic_tls_secret_t const * secret ); 44 : 45 : typedef void 46 : (* fd_quic_tls_cb_handshake_complete_t)( fd_quic_tls_hs_t * hs, 47 : void * context ); 48 : 49 : typedef void 50 : (* fd_quic_tls_cb_peer_params_t)( void * context, 51 : uchar const * quic_tp, 52 : ulong quic_tp_sz ); 53 : 54 : struct fd_quic_tls_secret { 55 : uint enc_level; 56 : uchar read_secret [ FD_QUIC_SECRET_SZ ]; 57 : uchar write_secret[ FD_QUIC_SECRET_SZ ]; 58 : }; 59 : 60 : struct fd_quic_tls_cfg { 61 : // callbacks ../crypto/fd_quic_crypto_suites 62 : fd_quic_tls_cb_secret_t secret_cb; 63 : fd_quic_tls_cb_handshake_complete_t handshake_complete_cb; 64 : fd_quic_tls_cb_peer_params_t peer_params_cb; 65 : 66 : ulong max_concur_handshakes; 67 : 68 : /* Signing callback for TLS 1.3 CertificateVerify. Context of the 69 : signer must outlive the tls object. */ 70 : fd_tls_sign_t signer; 71 : 72 : /* Ed25519 public key */ 73 : uchar const * cert_public_key; 74 : 75 : /* rng is a seeded CSPRNG used to generate the TLS random of every 76 : handshake. caller-managed, outlives quic_tls. */ 77 : fd_chacha_rng_t * rng; 78 : 79 : /* alpn: either "solana-tpu" or "alpenglow-v1" */ 80 : uchar const * alpn; 81 : ulong alpn_sz; 82 : 83 : /* req_client_cert: see fd_tls_t */ 84 : int req_client_cert; 85 : }; 86 : 87 : /* structure for organising handshake data */ 88 : struct fd_quic_tls_hs_data { 89 : uchar const * data; 90 : uint data_sz; 91 : uint free_data_sz; /* internal use */ 92 : uint offset; 93 : uint enc_level; 94 : 95 : /* internal use */ 96 : ushort next_idx; /* next in linked list, ~0 for end */ 97 : }; 98 : 99 : struct fd_quic_tls { 100 : /* callbacks */ 101 : fd_quic_tls_cb_secret_t secret_cb; 102 : fd_quic_tls_cb_handshake_complete_t handshake_complete_cb; 103 : fd_quic_tls_cb_peer_params_t peer_params_cb; 104 : 105 : /* ssl related */ 106 : fd_tls_t tls; 107 : }; 108 : 109 620862 : #define FD_QUIC_TLS_HS_DATA_UNUSED ((ushort)~0u) 110 : 111 : struct fd_quic_tls_hs { 112 : /* TLS handshake handles are deliberately placed at the start. 113 : Allows for type punning between fd_quic_tls_hs_t and 114 : fd_tls_estate_{srv,cli}_t. DO NOT MOVE. 115 : Type of handshake object depends on is_server. */ 116 : fd_tls_estate_t hs; 117 : 118 : fd_quic_tls_t * quic_tls; 119 : 120 : int is_server; 121 : int is_hs_complete; 122 : 123 : /* user defined context supplied in callbacks */ 124 : void * context; 125 : 126 : ulong next; /* alloc pool/cache dlist */ 127 : ulong prev; /* cache dlist */ 128 : long birthtime; /* allocation time, used for cache eviction sanity check */ 129 : 130 : /* handshake data 131 : this is data that must be sent to the peer 132 : it consists of an arbitrary list of tuples of: 133 : < "encryption level", array of bytes > 134 : these will be encapsulated and sent in order */ 135 : fd_quic_tls_hs_data_t hs_data[ FD_QUIC_TLS_HS_DATA_CNT ]; 136 : 137 : /* head of hs_data_t free list */ 138 : ushort hs_data_free_idx; 139 : 140 : /* head/tail of hs_data_t pending (to be sent) */ 141 : ushort hs_data_pend_idx[4]; 142 : ushort hs_data_pend_end_idx[4]; 143 : 144 : /* handshake data buffer 145 : allocated in arbitrary chunks 146 : and shared between encryption levels */ 147 : uchar hs_data_buf[ FD_QUIC_TLS_HS_DATA_SZ ]; 148 : uint hs_data_buf_ptr; /* ptr is first unused byte in hs_data_buf */ 149 : uint hs_data_offset[ 4 ]; /* one offset per encoding level */ 150 : 151 : /* Handshake message receive buffer 152 : 153 : rx_hs_buf buffers messages of one encryption level (rx_enc_level). 154 : rx_off is the number of bytes processed by fd_tls. rx_sz is the 155 : number of contiguous bytes received from the peer. */ 156 : 157 : ushort rx_off; 158 : ushort rx_sz; 159 : uchar rx_enc_level; 160 : 161 42489 : # define FD_QUIC_TLS_RX_DATA_SZ (2048UL) 162 : uchar rx_hs_buf[ FD_QUIC_TLS_RX_DATA_SZ ]; 163 : 164 : /* TLS alert code */ 165 : uint alert; 166 : 167 : /* our own QUIC transport params */ 168 : fd_quic_transport_params_t self_transport_params; 169 : 170 : }; 171 : 172 : /* fd_quic_tls_new formats an unused memory region for use as an 173 : fd_quic_tls_t object and joins the caller to it */ 174 : 175 : fd_quic_tls_t * 176 : fd_quic_tls_new( fd_quic_tls_t * mem, 177 : fd_quic_tls_cfg_t * cfg ); 178 : 179 : /* fd_quic_tls_delete unformats a memory region used as an fd_quic_tls_t. 180 : Returns the given pointer on success and NULL if used obviously in error. 181 : Deletes any fd_tls resources. */ 182 : 183 : void * 184 : fd_quic_tls_delete( fd_quic_tls_t * self ); 185 : 186 : fd_quic_tls_hs_t * 187 : fd_quic_tls_hs_new( fd_quic_tls_hs_t * self, 188 : fd_quic_tls_t * quic_tls, 189 : void * context, 190 : int is_server, 191 : fd_quic_transport_params_t const * self_transport_params, 192 : long now ); 193 : 194 : void 195 : fd_quic_tls_hs_delete( fd_quic_tls_hs_t * hs ); 196 : 197 : /* fd_quic_tls_process processes any available TLS handshake messages 198 : from previously received CRYPTO frames. Returns FD_QUIC_SUCCESS if 199 : any number of messages were processed (including no messages in there 200 : is not enough data). Returns FD_QUIC_FAILED if the TLS handshake 201 : failed (not recoverable). */ 202 : 203 : int 204 : fd_quic_tls_process( fd_quic_tls_hs_t * self ); 205 : 206 : 207 : /* fd_quic_tls_get_hs_data 208 : 209 : get oldest queued handshake data from the queue of pending data to sent to peer 210 : 211 : returns 212 : NULL there is no data available 213 : hd_data a pointer to the fd_quic_tls_hs_data_t structure at the head of the queue 214 : 215 : the hd_data and data therein are invalidated by the following 216 : fd_quic_tls_pop_hs_data 217 : fd_quic_tls_hs_delete 218 : 219 : args 220 : self the handshake in question (fine if NULL) 221 : enc_level a pointer for receiving the encryption level 222 : data a pointer for receiving the pointer to the data buffer 223 : data_sz a pointer for receiving the data size */ 224 : fd_quic_tls_hs_data_t * 225 : fd_quic_tls_get_hs_data( fd_quic_tls_hs_t * self, uint enc_level ); 226 : 227 : 228 : /* fd_quic_tls_get_next_hs_data 229 : 230 : get the next unit of handshake data from the queue 231 : 232 : returns NULL if no more available */ 233 : fd_quic_tls_hs_data_t * 234 : fd_quic_tls_get_next_hs_data( fd_quic_tls_hs_t * self, fd_quic_tls_hs_data_t * hs ); 235 : 236 : 237 : /* fd_quic_tls_pop_hs_data 238 : 239 : remove handshake data from head of queue and free associated resources */ 240 : void 241 : fd_quic_tls_pop_hs_data( fd_quic_tls_hs_t * self, uint enc_level ); 242 : 243 : 244 : /* fd_quic_tls_clear_hs_data 245 : 246 : clear all handshake data from a given encryption level. */ 247 : void 248 : fd_quic_tls_clear_hs_data( fd_quic_tls_hs_t * self, uint enc_level ); 249 : 250 : 251 : #endif /* HEADER_fd_src_waltz_quic_tls_fd_quic_tls_h */