From: Hugo Landau Date: Thu, 17 Aug 2023 09:00:02 +0000 (+0100) Subject: QUIC APL: Handle modes correctly X-Git-Tag: openssl-3.2.0-alpha1~130 X-Git-Url: https://git.openssl.org/gitweb/?a=commitdiff_plain;h=c5b882a80b9f5811e45e29f4492bf335e870eb35;p=openssl.git QUIC APL: Handle modes correctly Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/21764) --- diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index 71bd5e865b..2314cbb819 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -1306,9 +1306,25 @@ long ossl_quic_ctrl(SSL *s, int cmd, long larg, void *parg) case DTLS_CTRL_HANDLE_TIMEOUT: /* DTLSv1_handle_timeout */ /* For legacy compatibility with DTLS calls. */ return ossl_quic_handle_events(s) == 1 ? 1 : -1; + + /* Mask ctrls we shouldn't support for QUIC. */ + case SSL_CTRL_GET_READ_AHEAD: + case SSL_CTRL_SET_READ_AHEAD: + case SSL_CTRL_SET_MAX_SEND_FRAGMENT: + case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT: + case SSL_CTRL_SET_MAX_PIPELINES: + return 0; + default: - /* Probably a TLS related ctrl. Defer to our internal SSL object */ - return SSL_ctrl(ctx.qc->tls, cmd, larg, parg); + /* + * Probably a TLS related ctrl. Send back to the frontend SSL_ctrl + * implementation. Either SSL_ctrl will handle it itself by direct + * access into handshake layer state, or failing that, it will be passed + * to the handshake layer via the SSL_METHOD vtable. If the ctrl is not + * supported by anything, the handshake layer's ctrl method will finally + * return 0. + */ + return ossl_ctrl_internal(&ctx.qc->ssl, cmd, larg, parg, /*no_quic=*/1); } } diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index bda6a9c7be..06efb4380a 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -2899,22 +2899,37 @@ int SSL_new_session_ticket(SSL *s) } long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + return ossl_ctrl_internal(s, cmd, larg, parg, /*no_quic=*/0); +} + +long ossl_ctrl_internal(SSL *s, int cmd, long larg, void *parg, int no_quic) { long l; SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); - /* TODO(QUIC FUTURE): Special handling for some ctrls will be needed */ - if (sc == NULL) - return 0; + /* + * Routing of ctrl calls for QUIC is a little counterintuitive: + * + * - Firstly (no_quic=0), we pass the ctrl directly to our QUIC + * implementation in case it wants to handle the ctrl specially. + * + * - If our QUIC implementation does not care about the ctrl, it + * will reenter this function with no_quic=1 and we will try to handle + * it directly using the QCSO SSL object stub (not the handshake layer + * SSL object). This is important for e.g. the version configuration + * ctrls below, which must use s->defltmeth (and not sc->defltmeth). + * + * - If we don't handle a ctrl here specially, then processing is + * redirected to the handshake layer SSL object. + */ + if (!no_quic && IS_QUIC(s)) + return s->method->ssl_ctrl(s, cmd, larg, parg); switch (cmd) { case SSL_CTRL_GET_READ_AHEAD: - if (IS_QUIC(s)) - return 0; return RECORD_LAYER_get_read_ahead(&sc->rlayer); case SSL_CTRL_SET_READ_AHEAD: - if (IS_QUIC(s)) - return 0; l = RECORD_LAYER_get_read_ahead(&sc->rlayer); RECORD_LAYER_set_read_ahead(&sc->rlayer, larg); return l; @@ -2945,7 +2960,7 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) sc->max_cert_list = (size_t)larg; return l; case SSL_CTRL_SET_MAX_SEND_FRAGMENT: - if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH || IS_QUIC(s)) + if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) return 0; #ifndef OPENSSL_NO_KTLS if (sc->wbio != NULL && BIO_get_ktls_send(sc->wbio)) @@ -2957,12 +2972,12 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) sc->rlayer.wrlmethod->set_max_frag_len(sc->rlayer.wrl, larg); return 1; case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT: - if ((size_t)larg > sc->max_send_fragment || larg == 0 || IS_QUIC(s)) + if ((size_t)larg > sc->max_send_fragment || larg == 0) return 0; sc->split_send_fragment = larg; return 1; case SSL_CTRL_SET_MAX_PIPELINES: - if (larg < 1 || larg > SSL_MAX_PIPELINES || IS_QUIC(s)) + if (larg < 1 || larg > SSL_MAX_PIPELINES) return 0; sc->max_pipelines = larg; if (sc->rlayer.rrlmethod->set_max_pipelines != NULL) @@ -3007,7 +3022,10 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) case SSL_CTRL_GET_MAX_PROTO_VERSION: return sc->max_proto_version; default: - return s->method->ssl_ctrl(s, cmd, larg, parg); + if (IS_QUIC(s)) + return SSL_ctrl((SSL *)sc, cmd, larg, parg); + else + return s->method->ssl_ctrl(s, cmd, larg, parg); } } diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index 4da83ab692..96d2f30761 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -2999,6 +2999,8 @@ void ossl_ssl_set_custom_record_layer(SSL_CONNECTION *s, const OSSL_RECORD_METHOD *meth, void *rlarg); +long ossl_ctrl_internal(SSL *s, int cmd, long larg, void *parg, int no_quic); + /* * Options which no longer have any effect, but which can be implemented * as no-ops for QUIC.