Skip to content

Commit

Permalink
QUIC APL: Handle modes correctly
Browse files Browse the repository at this point in the history
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #21764)
  • Loading branch information
hlandau authored and t8m committed Aug 29, 2023
1 parent 777a8a7 commit c5b882a
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 13 deletions.
20 changes: 18 additions & 2 deletions ssl/quic/quic_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
40 changes: 29 additions & 11 deletions ssl/ssl_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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))
Expand All @@ -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)
Expand Down Expand Up @@ -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);
}
}

Expand Down
2 changes: 2 additions & 0 deletions ssl/ssl_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit c5b882a

Please sign in to comment.