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