summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/man3/SSL_CTX_set_options.pod20
-rw-r--r--ssl/quic/quic_channel.c9
-rw-r--r--ssl/quic/quic_impl.c70
-rw-r--r--ssl/quic/quic_local.h6
-rw-r--r--ssl/ssl_local.h16
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