summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2023-04-18 19:30:53 +0100
committerHugo Landau <hlandau@openssl.org>2023-05-12 14:46:03 +0100
commite88cdb8eb7b719803aaaef853db16abf3a4e73d1 (patch)
treeac854a4985c59f7c03f545423058b6b23a652fc9
parente0f1ec3b2ec1b137695abc3199a62def5965351f (diff)
downloadopenssl-new-e88cdb8eb7b719803aaaef853db16abf3a4e73d1.tar.gz
QUIC Dispatch: Enhance SSL object unwrapping functions (core)
Uniform changes to all dispatch functions to use the new dispatch functionality follows this commit. Separated into a core commit and a commit containing the uniform pattern (monotonous) changes for ease of review. Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/20765)
-rw-r--r--ssl/quic/quic_impl.c93
1 files changed, 88 insertions, 5 deletions
diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c
index e06a6e5fd1..dfc75c4555 100644
--- a/ssl/quic/quic_impl.c
+++ b/ssl/quic/quic_impl.c
@@ -59,6 +59,11 @@ static int quic_raise_normal_error(QUIC_CONNECTION *qc,
/*
* Raise a 'non-normal' error, meaning any error that is not reported via
* SSL_get_error() and must be reported via ERR.
+ *
+ * qc should be provided if available. In exceptional circumstances when qc is
+ * not known NULL may be passed. This should generally only happen when an
+ * expect_...() function defined below fails, which generally indicates a
+ * dispatch error or caller error.
*/
static int quic_raise_non_normal_error(QUIC_CONNECTION *qc,
const char *file,
@@ -77,7 +82,9 @@ static int quic_raise_non_normal_error(QUIC_CONNECTION *qc,
ERR_vset_error(ERR_LIB_SSL, reason, fmt, args);
va_end(args);
- qc->last_error = SSL_ERROR_SSL;
+ if (qc != NULL)
+ qc->last_error = SSL_ERROR_SSL;
+
return 0;
}
@@ -92,16 +99,92 @@ static int quic_raise_non_normal_error(QUIC_CONNECTION *qc,
(msg))
/*
- * Should be called at entry of every public function to confirm we have a valid
- * QUIC_CONNECTION.
+ * QCTX is a utility structure which provides information we commonly wish to
+ * unwrap upon an API call being dispatched to us, namely:
+ *
+ * - a pointer to the QUIC_CONNECTION (regardless of whether a QCSO or QSSO
+ * was passed);
+ * - a pointer to any applicable QUIC_XSO (e.g. if a QSSO was passed, or if
+ * a QCSO with a default stream was passed);
+ * - whether a QSSO was passed (xso == NULL must not be used to determine this
+ * because it may be non-NULL when a QCSO is passed if that QCSO has a
+ * default stream).
*/
-static ossl_inline int expect_quic_conn(const QUIC_CONNECTION *qc)
+typedef struct qctx_st {
+ QUIC_CONNECTION *qc;
+ QUIC_XSO *xso;
+ int is_stream;
+} QCTX;
+
+/*
+ * Given a QCSO or QSSO, initialises a QCTX, determining the contextually
+ * applicable QUIC_CONNECTION pointer and, if applicable, QUIC_XSO pointer.
+ *
+ * After this returns 1, all fields of the passed QCTX are initialised.
+ * Returns 0 on failure. This function is intended to be used to provide API
+ * semantics and as such, it invokes QUIC_RAISE_NON_NORMAL_ERROR() on failure.
+ */
+static int expect_quic(const SSL *s, QCTX *ctx)
{
- if (!ossl_assert(qc != NULL))
+ QUIC_CONNECTION *qc;
+ QUIC_XSO *xso;
+
+ ctx->qc = NULL;
+ ctx->xso = NULL;
+ ctx->is_stream = 0;
+
+ if (s == NULL)
+ return QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);
+
+ switch (s->type) {
+ case SSL_TYPE_QUIC_CONNECTION:
+ qc = (QUIC_CONNECTION *)s;
+ ctx->qc = qc;
+ ctx->xso = NULL; /* TODO XXX (Filled by subsequent commit) */
+ ctx->is_stream = 0;
+ return 1;
+
+ case SSL_TYPE_QUIC_XSO:
+ xso = (QUIC_XSO *)s;
+ ctx->qc = NULL; /* TODO XXX (Filled by subsequent commit) */
+ ctx->xso = xso;
+ ctx->is_stream = 1;
+ return 1;
+
+ default:
return QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);
+ }
+}
+
+/*
+ * Like expect_quic(), but requires a QUIC_XSO be contextually available. In
+ * other words, requires that the passed QSO be a QSSO or a QCSO with a default
+ * stream.
+ */
+static int expect_quic_with_stream(const SSL *s, QCTX *ctx)
+{
+ if (!expect_quic(s, ctx))
+ return 0;
+
+ if (ctx->xso == NULL)
+ return QUIC_RAISE_NON_NORMAL_ERROR(ctx->qc, ERR_R_INTERNAL_ERROR, NULL);
return 1;
+}
+
+/*
+ * Like expect_quic(), but fails if called on a QUIC_XSO. ctx->xso may still
+ * be non-NULL if the QCSO has a default stream.
+ */
+static int expect_quic_conn_only(const SSL *s, QCTX *ctx)
+{
+ if (!expect_quic(s, ctx))
+ return 0;
+ if (ctx->is_stream)
+ return QUIC_RAISE_NON_NORMAL_ERROR(ctx->qc, ERR_R_INTERNAL_ERROR, NULL);
+
+ return 1;
}
/*