2022-05-13 21:34:22 +08:00
|
|
|
/*
|
|
|
|
* Copyright 2022 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>
|
2022-09-06 19:59:25 +08:00
|
|
|
# include "internal/quic_ssl.h" /* QUIC_CONNECTION */
|
2022-11-17 23:33:11 +08:00
|
|
|
# include "internal/quic_txp.h"
|
|
|
|
# include "internal/quic_statm.h"
|
|
|
|
# include "internal/quic_demux.h"
|
|
|
|
# include "internal/quic_record_rx.h"
|
2022-11-18 20:38:50 +08:00
|
|
|
# include "internal/quic_tls.h"
|
2022-10-27 00:35:04 +08:00
|
|
|
# include "internal/quic_fc.h"
|
|
|
|
# include "internal/quic_stream.h"
|
2022-11-17 23:33:11 +08:00
|
|
|
# include "internal/quic_channel.h"
|
|
|
|
# include "internal/quic_reactor.h"
|
2023-02-21 18:18:59 +08:00
|
|
|
# include "internal/quic_thread_assist.h"
|
2022-05-13 21:34:22 +08:00
|
|
|
# include "../ssl_local.h"
|
|
|
|
|
2022-11-17 23:33:11 +08:00
|
|
|
# ifndef OPENSSL_NO_QUIC
|
2022-10-27 00:35:04 +08:00
|
|
|
|
|
|
|
struct quic_conn_st {
|
2022-11-17 23:33:11 +08:00
|
|
|
/*
|
|
|
|
* 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 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;
|
|
|
|
|
2023-02-21 18:18:58 +08:00
|
|
|
/*
|
|
|
|
* The mutex used to synchronise access to the QUIC_CHANNEL. We own this but
|
|
|
|
* provide it to the channel.
|
|
|
|
*/
|
2023-02-23 13:02:29 +08:00
|
|
|
CRYPTO_MUTEX *mutex;
|
2023-02-21 18:18:58 +08:00
|
|
|
|
2022-11-17 23:33:11 +08:00
|
|
|
/* Our single bidirectional application data stream. */
|
|
|
|
QUIC_STREAM *stream0;
|
|
|
|
|
|
|
|
/* The network read and write BIOs. */
|
|
|
|
BIO *net_rbio, *net_wbio;
|
|
|
|
|
|
|
|
/* Initial peer L4 address. */
|
|
|
|
BIO_ADDR init_peer_addr;
|
|
|
|
|
2023-03-21 23:19:34 +08:00
|
|
|
# ifndef OPENSSL_NO_QUIC_THREAD_ASSIST
|
2023-02-21 18:18:59 +08:00
|
|
|
/* Manages thread for QUIC thread assisted mode. */
|
|
|
|
QUIC_THREAD_ASSIST thread_assist;
|
2023-03-21 23:19:34 +08:00
|
|
|
# endif
|
2023-02-21 18:18:59 +08:00
|
|
|
|
2023-02-21 18:18:59 +08:00
|
|
|
/* If non-NULL, used instead of ossl_time_now(). Used for testing. */
|
|
|
|
OSSL_TIME (*override_now_cb)(void *arg);
|
|
|
|
void *override_now_cb_arg;
|
|
|
|
|
2022-11-17 23:33:11 +08:00
|
|
|
/* Have we started? */
|
|
|
|
unsigned int started : 1;
|
|
|
|
|
|
|
|
/* Are we in blocking mode? */
|
|
|
|
unsigned int blocking : 1;
|
|
|
|
|
|
|
|
/* Can the read and write network BIOs support blocking? */
|
|
|
|
unsigned int can_poll_net_rbio : 1;
|
|
|
|
unsigned int can_poll_net_wbio : 1;
|
|
|
|
|
|
|
|
/*
|
QUIC: Base client/server identity on SSL method, not SSL_set_connect/accept_state
In QUIC, we have an architectural need (in future, when we implement
0-RTT, etc.) to be able to create streams before we start connecting.
This requires we allocate a stream, including a stream ID, after
creating a QCSO but prior to connecting. However stream IDs are
dependent on whether the endpoint is in the client or server role,
therefore we must know whether we are going to be a client or server
before any pre-connection streams are created. Moreover, the originally
defined QUIC_client_method() and QUIC_server_method() functions heavily
implied the original plan was to have different SSL_METHODs for clients
and servers. Up until now we had been relying on
SSL_set_connect/accept_state() instead.
Solve these problems by basing client/server identity on whether
QUIC_server_method() is used (in future, when we support servers). This
ensures that once a QCSO is created its client/server identity are fixed
and cannot change, allowing pre-connection stream IDs, etc. to be
allocated.
Client/server uncertainty was the primary reason why QUIC_CHANNEL
creation was deferred until connection time up until now, so this
enables further refactoring to facilitate eager allocation of the
QUIC_CHANNEL at QCSO allocation time. This is important as allocating a
stream including its write buffers is hard without having the
QUIC_CHANNEL (which owns the QUIC_STREAM_MAP) in existence.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20765)
2023-04-19 02:30:54 +08:00
|
|
|
* This is 1 if we were instantiated using a QUIC server method
|
|
|
|
* (for future use).
|
2022-11-17 23:33:11 +08:00
|
|
|
*/
|
|
|
|
unsigned int as_server : 1;
|
|
|
|
|
QUIC: Base client/server identity on SSL method, not SSL_set_connect/accept_state
In QUIC, we have an architectural need (in future, when we implement
0-RTT, etc.) to be able to create streams before we start connecting.
This requires we allocate a stream, including a stream ID, after
creating a QCSO but prior to connecting. However stream IDs are
dependent on whether the endpoint is in the client or server role,
therefore we must know whether we are going to be a client or server
before any pre-connection streams are created. Moreover, the originally
defined QUIC_client_method() and QUIC_server_method() functions heavily
implied the original plan was to have different SSL_METHODs for clients
and servers. Up until now we had been relying on
SSL_set_connect/accept_state() instead.
Solve these problems by basing client/server identity on whether
QUIC_server_method() is used (in future, when we support servers). This
ensures that once a QCSO is created its client/server identity are fixed
and cannot change, allowing pre-connection stream IDs, etc. to be
allocated.
Client/server uncertainty was the primary reason why QUIC_CHANNEL
creation was deferred until connection time up until now, so this
enables further refactoring to facilitate eager allocation of the
QUIC_CHANNEL at QCSO allocation time. This is important as allocating a
stream including its write buffers is hard without having the
QUIC_CHANNEL (which owns the QUIC_STREAM_MAP) in existence.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20765)
2023-04-19 02:30:54 +08:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2023-02-21 18:18:59 +08:00
|
|
|
/* Are we using thread assisted mode? Never changes after init. */
|
|
|
|
unsigned int is_thread_assisted : 1;
|
|
|
|
|
2022-11-17 23:33:11 +08:00
|
|
|
/*
|
|
|
|
* 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_progess=0
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
/* Is an AON write in progress? */
|
|
|
|
unsigned int aon_write_in_progress : 1;
|
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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;
|
2022-09-06 19:59:25 +08:00
|
|
|
};
|
2022-06-20 23:11:28 +08:00
|
|
|
|
2022-11-17 23:33:11 +08:00
|
|
|
/* 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 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);
|
|
|
|
|
|
|
|
# define OSSL_QUIC_ANY_VERSION 0xFFFFF
|
|
|
|
|
|
|
|
# define QUIC_CONNECTION_FROM_SSL_int(ssl, c) \
|
|
|
|
((ssl) == NULL ? NULL \
|
|
|
|
: ((ssl)->type == SSL_TYPE_QUIC_CONNECTION \
|
|
|
|
? (c QUIC_CONNECTION *)(ssl) \
|
|
|
|
: NULL))
|
|
|
|
|
2023-04-19 02:30:53 +08:00
|
|
|
# define QUIC_XSO_FROM_SSL_int(ssl, c) \
|
2022-11-17 23:33:11 +08:00
|
|
|
((ssl) == NULL ? NULL \
|
|
|
|
: ((ssl)->type == SSL_TYPE_QUIC_CONNECTION \
|
2023-04-19 02:30:53 +08:00
|
|
|
|| (ssl)->type == SSL_TYPE_QUIC_XSO \
|
|
|
|
? (c QUIC_XSO *)(ssl) \
|
2022-11-17 23:33:11 +08:00
|
|
|
: 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))
|
2023-04-19 02:30:53 +08:00
|
|
|
|
|
|
|
# define IS_QUIC(ssl) ((ssl) != NULL \
|
|
|
|
&& ((ssl)->type == SSL_TYPE_QUIC_CONNECTION \
|
|
|
|
|| (ssl)->type == SSL_TYPE_QUIC_XSO))
|
2022-11-17 23:33:11 +08:00
|
|
|
# else
|
|
|
|
# define QUIC_CONNECTION_FROM_SSL_int(ssl, c) NULL
|
2023-04-19 02:30:53 +08:00
|
|
|
# define QUIC_XSO_FROM_SSL_int(ssl, c) NULL
|
2022-11-17 23:33:11 +08:00
|
|
|
# define SSL_CONNECTION_FROM_QUIC_SSL_int(ssl, c) NULL
|
2023-04-19 02:30:53 +08:00
|
|
|
# define IS_QUIC(ssl) 0
|
2022-11-17 23:33:11 +08:00
|
|
|
# endif
|
2022-06-20 23:11:28 +08:00
|
|
|
|
|
|
|
# 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)
|
2023-04-19 02:30:53 +08:00
|
|
|
# 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)
|
2022-06-20 23:11:28 +08:00
|
|
|
# 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)
|
|
|
|
|
2022-05-17 00:08:54 +08:00
|
|
|
# define IMPLEMENT_quic_meth_func(version, func_name, q_accept, \
|
|
|
|
q_connect, enc_data) \
|
2022-05-13 21:34:22 +08:00
|
|
|
const SSL_METHOD *func_name(void) \
|
|
|
|
{ \
|
|
|
|
static const SSL_METHOD func_name##_data= { \
|
|
|
|
version, \
|
|
|
|
0, \
|
|
|
|
0, \
|
|
|
|
ossl_quic_new, \
|
|
|
|
ossl_quic_free, \
|
2022-06-20 23:11:28 +08:00
|
|
|
ossl_quic_reset, \
|
|
|
|
ossl_quic_init, \
|
|
|
|
ossl_quic_clear, \
|
|
|
|
ossl_quic_deinit, \
|
2022-05-17 00:08:54 +08:00
|
|
|
q_accept, \
|
|
|
|
q_connect, \
|
2022-05-13 21:34:22 +08:00
|
|
|
ossl_quic_read, \
|
|
|
|
ossl_quic_peek, \
|
|
|
|
ossl_quic_write, \
|
2022-12-13 20:27:05 +08:00
|
|
|
NULL /* shutdown */, \
|
2022-05-13 21:34:22 +08:00
|
|
|
NULL /* renegotiate */, \
|
2022-05-13 22:45:07 +08:00
|
|
|
ossl_quic_renegotiate_check, \
|
2022-05-13 21:34:22 +08:00
|
|
|
NULL /* read_bytes */, \
|
|
|
|
NULL /* write_bytes */, \
|
|
|
|
NULL /* dispatch_alert */, \
|
|
|
|
ossl_quic_ctrl, \
|
|
|
|
ossl_quic_ctx_ctrl, \
|
|
|
|
NULL /* get_cipher_by_char */, \
|
|
|
|
NULL /* put_cipher_by_char */, \
|
|
|
|
ossl_quic_pending, \
|
2022-05-13 22:45:07 +08:00
|
|
|
ossl_quic_num_ciphers, \
|
|
|
|
ossl_quic_get_cipher, \
|
2022-11-17 23:33:11 +08:00
|
|
|
tls1_default_timeout, \
|
2022-05-13 21:34:22 +08:00
|
|
|
&enc_data, \
|
|
|
|
ssl_undefined_void_function, \
|
|
|
|
ossl_quic_callback_ctrl, \
|
|
|
|
ossl_quic_ctx_callback_ctrl, \
|
|
|
|
}; \
|
|
|
|
return &func_name##_data; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|