summaryrefslogtreecommitdiffstats
path: root/ssl/quic/quic_local.h
blob: d6518fd6b45225fc6383a0f87c0e0ca35525646c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
/*
 * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#ifndef OSSL_QUIC_LOCAL_H
# define OSSL_QUIC_LOCAL_H

# include <openssl/ssl.h>
# include "internal/quic_ssl.h"       /* QUIC_CONNECTION */
# include "internal/quic_txp.h"
# include "internal/quic_statm.h"
# include "internal/quic_demux.h"
# include "internal/quic_record_rx.h"
# include "internal/quic_tls.h"
# include "internal/quic_fc.h"
# include "internal/quic_stream.h"
# include "internal/quic_channel.h"
# include "internal/quic_reactor.h"
# include "internal/quic_thread_assist.h"
# include "../ssl_local.h"

# ifndef OPENSSL_NO_QUIC

/*
 * QUIC stream SSL object (QSSO) type. This implements the API personality layer
 * for QSSO objects, wrapping the QUIC-native QUIC_STREAM object and tracking
 * state required by the libssl API personality.
 */
struct quic_xso_st {
    /* SSL object common header. */
    struct ssl_st                   ssl;

    /* The connection this stream is associated with. Always non-NULL. */
    QUIC_CONNECTION                 *conn;

    /* The stream object. Always non-NULL for as long as the XSO exists. */
    QUIC_STREAM                     *stream;

    /*
     * Has this stream been logically configured into blocking mode? Only
     * meaningful if desires_blocking_set is 1. Ignored if blocking is not
     * currently possible given QUIC_CONNECTION configuration.
     */
    unsigned int                    desires_blocking        : 1;

    /*
     * Has SSL_set_blocking_mode been called on this stream? If not set, we
     * inherit from the QUIC_CONNECTION blocking state.
     */
    unsigned int                    desires_blocking_set    : 1;

    /* The application has retired a FIN (i.e. SSL_ERROR_ZERO_RETURN). */
    unsigned int                    retired_fin             : 1;

    /*
     * The application has requested a reset. Not set for reflexive
     * STREAM_RESETs caused by peer STOP_SENDING.
     */
    unsigned int                    requested_reset         : 1;

    /*
     * This state tracks SSL_write all-or-nothing (AON) write semantics
     * emulation.
     *
     * Example chronology:
     *
     *   t=0:  aon_write_in_progress=0
     *   t=1:  SSL_write(ssl, b1, l1) called;
     *         too big to enqueue into sstream at once, SSL_ERROR_WANT_WRITE;
     *         aon_write_in_progress=1; aon_buf_base=b1; aon_buf_len=l1;
     *         aon_buf_pos < l1 (depends on how much room was in sstream);
     *   t=2:  SSL_write(ssl, b2, l2);
     *         b2 must equal b1 (validated unless ACCEPT_MOVING_WRITE_BUFFER)
     *         l2 must equal l1 (always validated)
     *         append into sstream from [b2 + aon_buf_pos, b2 + aon_buf_len)
     *         if done, aon_write_in_progress=0
     *
     */
    /* Is an AON write in progress? */
    unsigned int                    aon_write_in_progress   : 1;

    /* Event handling mode. One of SSL_QUIC_VALUE_EVENT_HANDLING. */
    unsigned int                    event_handling_mode     : 2;

    /*
     * The base buffer pointer the caller passed us for the initial AON write
     * call. We use this for validation purposes unless
     * ACCEPT_MOVING_WRITE_BUFFER is enabled.
     *
     * NOTE: We never dereference this, as the caller might pass a different
     * (but identical) buffer if using ACCEPT_MOVING_WRITE_BUFFER. It is for
     * validation by pointer comparison only.
     */
    const unsigned char             *aon_buf_base;
    /* The total length of the AON buffer being sent, in bytes. */
    size_t                          aon_buf_len;
    /*
     * The position in the AON buffer up to which we have successfully sent data
     * so far.
     */
    size_t                          aon_buf_pos;

    /* SSL_set_mode */
    uint32_t                        ssl_mode;

    /* SSL_set_options */
    uint64_t                        ssl_options;

    /*
     * Last 'normal' error during an app-level I/O operation, used by
     * SSL_get_error(); used to track data-path errors like SSL_ERROR_WANT_READ
     * and SSL_ERROR_WANT_WRITE.
     */
    int                             last_error;
};

struct quic_conn_st {
    /*
     * ssl_st is a common header for ordinary SSL objects, QUIC connection
     * objects and QUIC stream objects, allowing objects of these different
     * types to be disambiguated at runtime and providing some common fields.
     *
     * Note: This must come first in the QUIC_CONNECTION structure.
     */
    struct ssl_st                   ssl;

    SSL                             *tls;

    /* The QUIC engine representing the QUIC event domain. */
    QUIC_ENGINE                     *engine;

    /* The QUIC port representing the QUIC listener and socket. */
    QUIC_PORT                       *port;

    /*
     * The QUIC channel providing the core QUIC connection implementation. Note
     * that this is not instantiated until we actually start trying to do the
     * handshake. This is to allow us to gather information like whether we are
     * going to be in client or server mode before committing to instantiating
     * the channel, since we want to determine the channel arguments based on
     * that.
     *
     * The channel remains available after connection termination until the SSL
     * object is freed, thus (ch != NULL) iff (started == 1).
     */
    QUIC_CHANNEL                    *ch;

    /*
     * The mutex used to synchronise access to the QUIC_CHANNEL. We own this but
     * provide it to the channel.
     */
    CRYPTO_MUTEX                    *mutex;

    /*
     * If we have a default stream attached, this is the internal XSO
     * object. If there is no default stream, this is NULL.
     */
    QUIC_XSO                        *default_xso;

    /* The network read and write BIOs. */
    BIO                             *net_rbio, *net_wbio;

    /* Initial peer L4 address. */
    BIO_ADDR                        init_peer_addr;

#  ifndef OPENSSL_NO_QUIC_THREAD_ASSIST
    /* Manages thread for QUIC thread assisted mode. */
    QUIC_THREAD_ASSIST              thread_assist;
#  endif

    /* If non-NULL, used instead of ossl_time_now(). Used for testing. */
    OSSL_TIME                       (*override_now_cb)(void *arg);
    void                            *override_now_cb_arg;

    /* Number of XSOs allocated. Includes the default XSO, if any. */
    size_t                          num_xso;

    /* Have we started? */
    unsigned int                    started                 : 1;

    /*
     * This is 1 if we were instantiated using a QUIC server method
     * (for future use).
     */
    unsigned int                    as_server               : 1;

    /*
     * Has the application called SSL_set_accept_state? We require this to be
     * congruent with the value of as_server.
     */
    unsigned int                    as_server_state         : 1;

    /* Are we using thread assisted mode? Never changes after init. */
    unsigned int                    is_thread_assisted      : 1;

    /* Do connection-level operations (e.g. handshakes) run in blocking mode? */
    unsigned int                    blocking                : 1;

    /* Does the application want blocking mode? */
    unsigned int                    desires_blocking        : 1;

    /* Have we created a default XSO yet? */
    unsigned int                    default_xso_created     : 1;

    /*
     * Pre-TERMINATING shutdown phase in which we are flushing streams.
     * Monotonically transitions to 1.
     * New streams cannot be created in this state.
     */
    unsigned int                    shutting_down           : 1;

    /* Have we probed the BIOs for addressing support? */
    unsigned int                    addressing_probe_done   : 1;

    /* Are we using addressed mode (BIO_sendmmsg with non-NULL peer)? */
    unsigned int                    addressed_mode_w        : 1;
    unsigned int                    addressed_mode_r        : 1;

    /* Event handling mode. One of SSL_QUIC_VALUE_EVENT_HANDLING. */
    unsigned int                    event_handling_mode     : 2;

    /* Default stream type. Defaults to SSL_DEFAULT_STREAM_MODE_AUTO_BIDI. */
    uint32_t                        default_stream_mode;

    /* SSL_set_mode. This is not used directly but inherited by new XSOs. */
    uint32_t                        default_ssl_mode;

    /* SSL_set_options. This is not used directly but inherited by new XSOs. */
    uint64_t                        default_ssl_options;

    /* SSL_set_incoming_stream_policy. */
    int                             incoming_stream_policy;
    uint64_t                        incoming_stream_aec;

    /*
     * Last 'normal' error during an app-level I/O operation, used by
     * SSL_get_error(); used to track data-path errors like SSL_ERROR_WANT_READ
     * and SSL_ERROR_WANT_WRITE.
     */
    int                             last_error;
};

/* Internal calls to the QUIC CSM which come from various places. */
int ossl_quic_conn_on_handshake_confirmed(QUIC_CONNECTION *qc);

/*
 * To be called when a protocol violation occurs. The connection is torn down
 * with the given error code, which should be a OSSL_QUIC_ERR_* value. Reason
 * string is optional and copied if provided. frame_type should be 0 if not
 * applicable.
 */
void ossl_quic_conn_raise_protocol_error(QUIC_CONNECTION *qc,
                                         uint64_t error_code,
                                         uint64_t frame_type,
                                         const char *reason);

void ossl_quic_conn_on_remote_conn_close(QUIC_CONNECTION *qc,
                                         OSSL_QUIC_FRAME_CONN_CLOSE *f);

int ossl_quic_trace(int write_p, int version, int content_type,
                    const void *buf, size_t msglen, SSL *ssl, void *arg);

#  define OSSL_QUIC_ANY_VERSION 0xFFFFF
#  define IS_QUIC_METHOD(m) \
    ((m) == OSSL_QUIC_client_method() || \
     (m) == OSSL_QUIC_client_thread_method())
#  define IS_QUIC_CTX(ctx)          IS_QUIC_METHOD((ctx)->method)

#  define QUIC_CONNECTION_FROM_SSL_int(ssl, c)   \
     ((ssl) == NULL ? NULL                       \
      : ((ssl)->type == SSL_TYPE_QUIC_CONNECTION \
         ? (c QUIC_CONNECTION *)(ssl)            \
         : NULL))

#  define QUIC_XSO_FROM_SSL_int(ssl, c)                             \
    ((ssl) == NULL                                                  \
     ? NULL                                                         \
     : (((ssl)->type == SSL_TYPE_QUIC_XSO                           \
        ? (c QUIC_XSO *)(ssl)                                       \
        : ((ssl)->type == SSL_TYPE_QUIC_CONNECTION                  \
           ? (c QUIC_XSO *)((QUIC_CONNECTION *)(ssl))->default_xso  \
           : NULL))))

#  define SSL_CONNECTION_FROM_QUIC_SSL_int(ssl, c)               \
     ((ssl) == NULL ? NULL                                       \
      : ((ssl)->type == SSL_TYPE_QUIC_CONNECTION                 \
         ? (c SSL_CONNECTION *)((c QUIC_CONNECTION *)(ssl))->tls \
         : NULL))

#  define IS_QUIC(ssl) ((ssl) != NULL                                   \
                        && ((ssl)->type == SSL_TYPE_QUIC_CONNECTION     \
                            || (ssl)->type == SSL_TYPE_QUIC_XSO))
# else
#  define QUIC_CONNECTION_FROM_SSL_int(ssl, c) NULL
#  define QUIC_XSO_FROM_SSL_int(ssl, c) NULL
#  define SSL_CONNECTION_FROM_QUIC_SSL_int(ssl, c) NULL
#  define IS_QUIC(ssl) 0
#  define IS_QUIC_CTX(ctx) 0
#  define IS_QUIC_METHOD(m) 0
# endif

# define QUIC_CONNECTION_FROM_SSL(ssl) \
    QUIC_CONNECTION_FROM_SSL_int(ssl, SSL_CONNECTION_NO_CONST)
# define QUIC_CONNECTION_FROM_CONST_SSL(ssl) \
    QUIC_CONNECTION_FROM_SSL_int(ssl, const)
# define QUIC_XSO_FROM_SSL(ssl) \
    QUIC_XSO_FROM_SSL_int(ssl, SSL_CONNECTION_NO_CONST)
# define QUIC_XSO_FROM_CONST_SSL(ssl) \
    QUIC_XSO_FROM_SSL_int(ssl, const)
# define SSL_CONNECTION_FROM_QUIC_SSL(ssl) \
    SSL_CONNECTION_FROM_QUIC_SSL_int(ssl, SSL_CONNECTION_NO_CONST)
# define SSL_CONNECTION_FROM_CONST_QUIC_SSL(ssl) \
    SSL_CONNECTION_FROM_CONST_QUIC_SSL_int(ssl, const)

# define IMPLEMENT_quic_meth_func(version, func_name, q_accept, \
                                 q_connect, enc_data) \
const SSL_METHOD *func_name(void)  \
        { \
        static const SSL_METHOD func_name##_data= { \
                version, \
                0, \
                0, \
                ossl_quic_new, \
                ossl_quic_free, \
                ossl_quic_reset, \
                ossl_quic_init, \
                NULL /* clear */, \
                ossl_quic_deinit, \
                q_accept, \
                q_connect, \
                ossl_quic_read, \
                ossl_quic_peek, \
                ossl_quic_write, \
                NULL /* shutdown */, \
                NULL /* renegotiate */, \
                ossl_quic_renegotiate_check, \
                NULL /* read_bytes */, \
                NULL /* write_bytes */, \
                NULL /* dispatch_alert */, \
                ossl_quic_ctrl, \
                ossl_quic_ctx_ctrl, \
                ossl_quic_get_cipher_by_char, \
                NULL /* put_cipher_by_char */, \
                ossl_quic_pending, \
                ossl_quic_num_ciphers, \
                ossl_quic_get_cipher, \
                tls1_default_timeout, \
                &enc_data, \
                ssl_undefined_void_function, \
                ossl_quic_callback_ctrl, \
                ossl_quic_ctx_callback_ctrl, \
        }; \
        return &func_name##_data; \
        }

#endif