summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2023-08-31 15:31:42 +0100
committerHugo Landau <hlandau@openssl.org>2023-09-02 15:23:47 +0100
commit3a0012cb52bef4df54bd46946d7ff783c24b4305 (patch)
treef8312172f88d1132aad5e203853bfa9247ba6057 /ssl
parent7b8e27bc2e02238986d89ef0ece067ec1b48e165 (diff)
Handle non IO based retry errors in QUIC
SSL_get_error() may respond with some retry errors that are not IO related. In particular SSL_ERROR_WANT_RETRY_VERIFY and SSL_ERROR_WANT_X509_LOOKUP. These can occur during a TLS handshake. If they occur when a QUIC Connection is performing a TLS handshake then we need to propagate these up to the QCSO. We also handle SSL_ERROR_WANT_CLIENT_HELLO_CB. This one will only ever occur on the server side which we don't currently support. However adding the handling for it now is identical to all the other handling so including it is no cost, and will be needed when we do add server support. We are not concerned with SSL_ERROR_WANT_ASYNC or SSL_ERROR_WANT_ASYNC_JOB since we do not support async operation with QUIC. Fixes openssl/project#199 Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Hugo Landau <hlandau@openssl.org> (Merged from https://github.com/openssl/openssl/pull/21922)
Diffstat (limited to 'ssl')
-rw-r--r--ssl/quic/quic_impl.c28
-rw-r--r--ssl/quic/quic_tls.c3
2 files changed, 31 insertions, 0 deletions
diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c
index 71c1536102..c43f8a7fc8 100644
--- a/ssl/quic/quic_impl.c
+++ b/ssl/quic/quic_impl.c
@@ -1445,6 +1445,18 @@ struct quic_handshake_wait_args {
QUIC_CONNECTION *qc;
};
+static int tls_wants_non_io_retry(QUIC_CONNECTION *qc)
+{
+ int want = SSL_want(qc->tls);
+
+ if (want == SSL_X509_LOOKUP
+ || want == SSL_CLIENT_HELLO_CB
+ || want == SSL_RETRY_VERIFY)
+ return 1;
+
+ return 0;
+}
+
static int quic_handshake_wait(void *arg)
{
struct quic_handshake_wait_args *args = arg;
@@ -1455,6 +1467,9 @@ static int quic_handshake_wait(void *arg)
if (ossl_quic_channel_is_handshake_complete(args->qc->ch))
return 1;
+ if (tls_wants_non_io_retry(args->qc))
+ return 1;
+
return 0;
}
@@ -1680,10 +1695,20 @@ static int quic_do_handshake(QCTX *ctx)
return -1; /* Non-protocol error */
}
+ if (tls_wants_non_io_retry(qc)) {
+ QUIC_RAISE_NORMAL_ERROR(ctx, SSL_get_error(qc->tls, 0));
+ return -1;
+ }
+
assert(ossl_quic_channel_is_handshake_complete(qc->ch));
return 1;
}
+ if (tls_wants_non_io_retry(qc)) {
+ QUIC_RAISE_NORMAL_ERROR(ctx, SSL_get_error(qc->tls, 0));
+ return -1;
+ }
+
/*
* Otherwise, indicate that the handshake isn't done yet.
* We can only get here in non-blocking mode.
@@ -2069,6 +2094,9 @@ static int error_to_want(int error)
case SSL_ERROR_WANT_WRITE:
return SSL_WRITING;
+ case SSL_ERROR_WANT_RETRY_VERIFY:
+ return SSL_RETRY_VERIFY;
+
case SSL_ERROR_WANT_CLIENT_HELLO_CB:
return SSL_CLIENT_HELLO_CB;
diff --git a/ssl/quic/quic_tls.c b/ssl/quic/quic_tls.c
index b0da216e37..ff4c8dac0b 100644
--- a/ssl/quic/quic_tls.c
+++ b/ssl/quic/quic_tls.c
@@ -798,6 +798,9 @@ int ossl_quic_tls_tick(QUIC_TLS *qtls)
switch (err) {
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_CLIENT_HELLO_CB:
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ case SSL_ERROR_WANT_RETRY_VERIFY:
ERR_pop_to_mark();
return 1;