diff options
-rw-r--r-- | doc/man3/SSL_CTX_set_options.pod | 20 | ||||
-rw-r--r-- | ssl/quic/quic_channel.c | 9 | ||||
-rw-r--r-- | ssl/quic/quic_impl.c | 70 | ||||
-rw-r--r-- | ssl/quic/quic_local.h | 6 | ||||
-rw-r--r-- | ssl/ssl_local.h | 16 |
5 files changed, 86 insertions, 35 deletions
diff --git a/doc/man3/SSL_CTX_set_options.pod b/doc/man3/SSL_CTX_set_options.pod index 3605c7e642..dd30873f36 100644 --- a/doc/man3/SSL_CTX_set_options.pod +++ b/doc/man3/SSL_CTX_set_options.pod @@ -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. + +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. -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. +Other options not mentioned above do not have an effect and will be ignored. -Connection and stream relevant options are initialized from the options -set on SSL_CTX before the connection or stream objects are created. +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 diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index fe04dffa34..576782c4f1 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -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)) diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index 696a660cd4..4866f52562 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -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); + /* 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->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); + 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: diff --git a/ssl/quic/quic_local.h b/ssl/quic/quic_local.h index 547c47de05..7e257825c8 100644 --- a/ssl/quic/quic_local.h +++ b/ssl/quic/quic_local.h @@ -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; diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index a24ec27e5a..82747f6dfb 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -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 |