Rework options handling
Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/20061)
This commit is contained in:
parent
9562842b33
commit
db2f98c4eb
@ -469,8 +469,6 @@ These options apply to SSL objects referencing a QUIC connection:
|
||||
|
||||
=back
|
||||
|
||||
Other options do not have an effect and will be ignored.
|
||||
|
||||
These options apply to SSL objects referencing a QUIC stream:
|
||||
|
||||
=over 4
|
||||
@ -479,14 +477,20 @@ These options apply to SSL objects referencing a QUIC stream:
|
||||
|
||||
=back
|
||||
|
||||
Other options do not have an effect and will be ignored.
|
||||
Options on QUIC connections are initialized from the options set on SSL_CTX
|
||||
before a QUIC connection SSL object is created. Options on QUIC streams are
|
||||
initialised from the options configured on the QUIC connection SSL object
|
||||
they are created from.
|
||||
|
||||
If an SSL object is a QUIC connection object with a default stream attached,
|
||||
only the stream-relevant options are applied. If it is a QUIC connection
|
||||
without a default stream, the stream-relevant options are ignored.
|
||||
Setting options which relate to QUIC streams on a QUIC connection SSL object has
|
||||
no direct effect on the QUIC connection SSL object itself, but will change the
|
||||
options set on the default stream (if there is one) and will also determine the
|
||||
default options set on any future streams which are created.
|
||||
|
||||
Connection and stream relevant options are initialized from the options
|
||||
set on SSL_CTX before the connection or stream objects are created.
|
||||
Other options not mentioned above do not have an effect and will be ignored.
|
||||
|
||||
Options which relate to QUIC streams may also be set directly on QUIC stream SSL
|
||||
objects. Setting connection-related options on such an object has no effect.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
|
@ -2700,19 +2700,14 @@ static int ch_init_new_stream(QUIC_CHANNEL *ch, QUIC_STREAM *qs,
|
||||
int server_init = ossl_quic_stream_is_server_init(qs);
|
||||
int local_init = (ch->is_server == server_init);
|
||||
int is_uni = !ossl_quic_stream_is_bidi(qs);
|
||||
int cleanse = (ch->tls->ctx->options & SSL_OP_CLEANSE_PLAINTEXT) != 0;
|
||||
|
||||
if (can_send) {
|
||||
if (can_send)
|
||||
if ((qs->sstream = ossl_quic_sstream_new(INIT_APP_BUF_LEN)) == NULL)
|
||||
goto err;
|
||||
ossl_quic_sstream_set_cleanse(qs->sstream, cleanse);
|
||||
}
|
||||
|
||||
if (can_recv) {
|
||||
if (can_recv)
|
||||
if ((qs->rstream = ossl_quic_rstream_new(NULL, NULL, 0)) == NULL)
|
||||
goto err;
|
||||
ossl_quic_rstream_set_cleanse(qs->rstream, cleanse);
|
||||
}
|
||||
|
||||
/* TXFC */
|
||||
if (!ossl_quic_txfc_init(&qs->txfc, &ch->conn_txfc))
|
||||
|
@ -331,7 +331,7 @@ SSL *ossl_quic_new(SSL_CTX *ctx)
|
||||
sc->s3.flags |= TLS1_FLAGS_QUIC;
|
||||
|
||||
/* Restrict options derived from the SSL_CTX. */
|
||||
sc->options &= OSSL_QUIC_PERMITTED_OPTIONS;
|
||||
sc->options &= OSSL_QUIC_PERMITTED_OPTIONS_CONN;
|
||||
sc->pha_enabled = 0;
|
||||
|
||||
#if defined(OPENSSL_THREADS)
|
||||
@ -349,6 +349,7 @@ SSL *ossl_quic_new(SSL_CTX *ctx)
|
||||
|
||||
qc->default_stream_mode = SSL_DEFAULT_STREAM_MODE_AUTO_BIDI;
|
||||
qc->default_ssl_mode = qc->ssl.ctx->mode;
|
||||
qc->default_ssl_options = qc->ssl.ctx->options & OSSL_QUIC_PERMITTED_OPTIONS;
|
||||
qc->default_blocking = 1;
|
||||
qc->blocking = 1;
|
||||
qc->incoming_stream_policy = SSL_INCOMING_STREAM_POLICY_AUTO;
|
||||
@ -616,38 +617,70 @@ static void qc_set_default_xso(QUIC_CONNECTION *qc, QUIC_XSO *xso, int touch)
|
||||
SSL_free(&old_xso->ssl);
|
||||
}
|
||||
|
||||
/* SSL_set_options */
|
||||
QUIC_NEEDS_LOCK
|
||||
static void xso_update_options(QUIC_XSO *xso)
|
||||
{
|
||||
int cleanse = ((xso->ssl_options & SSL_OP_CLEANSE_PLAINTEXT) != 0);
|
||||
|
||||
if (xso->stream->rstream != NULL)
|
||||
ossl_quic_rstream_set_cleanse(xso->stream->rstream, cleanse);
|
||||
|
||||
if (xso->stream->sstream != NULL)
|
||||
ossl_quic_sstream_set_cleanse(xso->stream->sstream, cleanse);
|
||||
}
|
||||
|
||||
/*
|
||||
* SSL_set_options
|
||||
* ---------------
|
||||
*
|
||||
* Setting options on a QCSO
|
||||
* - configures the handshake-layer options;
|
||||
* - configures the default data-plane options for new streams;
|
||||
* - configures the data-plane options on the default XSO, if there is one.
|
||||
*
|
||||
* Setting options on a QSSO
|
||||
* - configures data-plane options for that stream only.
|
||||
*/
|
||||
QUIC_TAKES_LOCK
|
||||
static uint64_t quic_mask_or_options(SSL *ssl, uint64_t mask_value, uint64_t or_value)
|
||||
{
|
||||
QCTX ctx;
|
||||
uint64_t options;
|
||||
uint64_t hs_mask_value, hs_or_value, ret;
|
||||
|
||||
if (!expect_quic(ssl, &ctx))
|
||||
return 0;
|
||||
|
||||
quic_lock(ctx.qc);
|
||||
|
||||
/*
|
||||
* Currently most options that we permit are handled in the handshake
|
||||
* layer.
|
||||
*/
|
||||
or_value &= OSSL_QUIC_PERMITTED_OPTIONS;
|
||||
if (!ctx.is_stream) {
|
||||
/*
|
||||
* If we were called on the connection, we apply any handshake option
|
||||
* changes.
|
||||
*/
|
||||
hs_mask_value = (mask_value & OSSL_QUIC_PERMITTED_OPTIONS_CONN);
|
||||
hs_or_value = (or_value & OSSL_QUIC_PERMITTED_OPTIONS_CONN);
|
||||
|
||||
SSL_clear_options(ctx.qc->tls, mask_value);
|
||||
options = SSL_set_options(ctx.qc->tls, or_value);
|
||||
SSL_clear_options(ctx.qc->tls, hs_mask_value);
|
||||
SSL_set_options(ctx.qc->tls, hs_or_value);
|
||||
|
||||
if (ctx.xso != NULL && ctx.xso->stream != NULL) {
|
||||
int cleanse = ((options & SSL_OP_CLEANSE_PLAINTEXT) != 0);
|
||||
|
||||
if (ctx.xso->stream->rstream != NULL)
|
||||
ossl_quic_rstream_set_cleanse(ctx.xso->stream->rstream, cleanse);
|
||||
if (ctx.xso->stream->sstream != NULL)
|
||||
ossl_quic_sstream_set_cleanse(ctx.xso->stream->sstream, cleanse);
|
||||
/* Update defaults for new streams. */
|
||||
ctx.qc->default_ssl_options
|
||||
= ((ctx.qc->default_ssl_options & ~mask_value) | or_value)
|
||||
& OSSL_QUIC_PERMITTED_OPTIONS;
|
||||
}
|
||||
|
||||
if (ctx.xso != NULL) {
|
||||
ctx.xso->ssl_options
|
||||
= ((ctx.xso->ssl_options & ~mask_value) | or_value)
|
||||
& OSSL_QUIC_PERMITTED_OPTIONS_STREAM;
|
||||
|
||||
xso_update_options(ctx.xso);
|
||||
}
|
||||
|
||||
ret = ctx.is_stream ? ctx.xso->ssl_options : ctx.qc->default_ssl_options;
|
||||
|
||||
quic_unlock(ctx.qc);
|
||||
return options;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t ossl_quic_set_options(SSL *ssl, uint64_t options)
|
||||
@ -1542,11 +1575,14 @@ static QUIC_XSO *create_xso_from_stream(QUIC_CONNECTION *qc, QUIC_STREAM *qs)
|
||||
xso->conn = qc;
|
||||
xso->blocking = qc->default_blocking;
|
||||
xso->ssl_mode = qc->default_ssl_mode;
|
||||
xso->ssl_options
|
||||
= qc->default_ssl_options & OSSL_QUIC_PERMITTED_OPTIONS_STREAM;
|
||||
xso->last_error = SSL_ERROR_NONE;
|
||||
|
||||
xso->stream = qs;
|
||||
|
||||
++qc->num_xso;
|
||||
xso_update_options(xso);
|
||||
return xso;
|
||||
|
||||
err:
|
||||
|
@ -85,6 +85,9 @@ struct quic_xso_st {
|
||||
/* 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
|
||||
@ -185,6 +188,9 @@ struct quic_conn_st {
|
||||
/* 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;
|
||||
|
@ -3044,8 +3044,8 @@ void ossl_ssl_set_custom_record_layer(SSL_CONNECTION *s,
|
||||
SSL_OP_LEGACY_SERVER_CONNECT | \
|
||||
SSL_OP_IGNORE_UNEXPECTED_EOF )
|
||||
|
||||
/* Total mask of options permitted or ignored under QUIC. */
|
||||
#define OSSL_QUIC_PERMITTED_OPTIONS \
|
||||
/* Total mask of connection-level options permitted or ignored under QUIC. */
|
||||
#define OSSL_QUIC_PERMITTED_OPTIONS_CONN \
|
||||
(OSSL_LEGACY_SSL_OPTIONS | \
|
||||
OSSL_TLS1_2_OPTIONS | \
|
||||
SSL_OP_CIPHER_SERVER_PREFERENCE | \
|
||||
@ -3053,9 +3053,19 @@ void ossl_ssl_set_custom_record_layer(SSL_CONNECTION *s,
|
||||
SSL_OP_NO_TX_CERTIFICATE_COMPRESSION | \
|
||||
SSL_OP_NO_RX_CERTIFICATE_COMPRESSION | \
|
||||
SSL_OP_PRIORITIZE_CHACHA | \
|
||||
SSL_OP_CLEANSE_PLAINTEXT | \
|
||||
SSL_OP_NO_QUERY_MTU | \
|
||||
SSL_OP_NO_TICKET | \
|
||||
SSL_OP_NO_ANTI_REPLAY )
|
||||
|
||||
/* Total mask of stream-level options permitted or ignored under QUIC. */
|
||||
#define OSSL_QUIC_PERMITTED_OPTIONS_STREAM \
|
||||
(OSSL_LEGACY_SSL_OPTIONS | \
|
||||
OSSL_TLS1_2_OPTIONS | \
|
||||
SSL_OP_CLEANSE_PLAINTEXT )
|
||||
|
||||
/* Total mask of options permitted on either connections or streams. */
|
||||
#define OSSL_QUIC_PERMITTED_OPTIONS \
|
||||
(OSSL_QUIC_PERMITTED_OPTIONS_CONN | \
|
||||
OSSL_QUIC_PERMITTED_OPTIONS_STREAM)
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user