diff options
author | Matt Caswell <matt@openssl.org> | 2022-11-29 11:26:08 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2023-01-24 17:16:29 +0000 |
commit | 4e3a55fd14cb4424fd62516345d918cdf0d9cdcc (patch) | |
tree | 34182d4cac374cde52a242d1b04ea14c2f02d59d /ssl | |
parent | c28f1a8bb9ccfecb76bcf3b7987e2a526b427bca (diff) |
Add QUIC-TLS server support
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19748)
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/quic/quic_impl.c | 2 | ||||
-rw-r--r-- | ssl/quic/quic_tls.c | 30 | ||||
-rw-r--r-- | ssl/quic/quic_tserver.c | 41 |
3 files changed, 60 insertions, 13 deletions
diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index 4331e6412b..5b895cb48a 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -131,7 +131,7 @@ SSL *ossl_quic_new(SSL_CTX *ctx) goto err; } - qc->tls = ossl_ssl_connection_new_int(ctx, TLS_client_method()); + qc->tls = ossl_ssl_connection_new_int(ctx, TLS_method()); if (qc->tls == NULL || (sc = SSL_CONNECTION_FROM_SSL(qc->tls)) == NULL) goto err; /* override the user_ssl of the inner connection */ diff --git a/ssl/quic/quic_tls.c b/ssl/quic/quic_tls.c index d7e3dd4acd..5ce71a2e4f 100644 --- a/ssl/quic/quic_tls.c +++ b/ssl/quic/quic_tls.c @@ -641,6 +641,7 @@ int ossl_quic_tls_tick(QUIC_TLS *qtls) if (!qtls->configured) { SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(qtls->args.s); + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(sc); BIO *nullbio; /* @@ -649,9 +650,16 @@ int ossl_quic_tls_tick(QUIC_TLS *qtls) */ /* ALPN is a requirement for QUIC and must be set */ - if (sc->ext.alpn == NULL || sc->ext.alpn_len == 0) { - qtls->inerror = 1; - return 0; + if (qtls->args.is_server) { + if (sctx->ext.alpn_select_cb == NULL) { + qtls->inerror = 1; + return 0; + } + } else { + if (sc->ext.alpn == NULL || sc->ext.alpn_len == 0) { + qtls->inerror = 1; + return 0; + } } if (!SSL_set_min_proto_version(qtls->args.s, TLS1_3_VERSION)) { qtls->inerror = 1; @@ -661,7 +669,8 @@ int ossl_quic_tls_tick(QUIC_TLS *qtls) ossl_ssl_set_custom_record_layer(sc, &quic_tls_record_method, qtls); if (!ossl_tls_add_custom_ext_intern(NULL, &sc->cert->custext, - ENDPOINT_CLIENT, + qtls->args.is_server ? ENDPOINT_SERVER + : ENDPOINT_CLIENT, TLSEXT_TYPE_quic_transport_parameters, SSL_EXT_TLS1_3_ONLY | SSL_EXT_CLIENT_HELLO @@ -685,9 +694,14 @@ int ossl_quic_tls_tick(QUIC_TLS *qtls) */ SSL_set_bio(qtls->args.s, nullbio, nullbio); + if (qtls->args.is_server) + SSL_set_accept_state(qtls->args.s); + else + SSL_set_connect_state(qtls->args.s); + qtls->configured = 1; } - ret = SSL_connect(qtls->args.s); + ret = SSL_do_handshake(qtls->args.s); if (ret <= 0) { switch (SSL_get_error(qtls->args.s, ret)) { case SSL_ERROR_WANT_READ: @@ -713,12 +727,6 @@ int ossl_quic_tls_set_transport_params(QUIC_TLS *qtls, const unsigned char *transport_params, size_t transport_params_len) { - if (!ossl_assert(!qtls->args.is_server)) { - ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - qtls->inerror = 1; - return 0; - } - qtls->local_transport_params = transport_params; qtls->local_transport_params_len = transport_params_len; return 1; diff --git a/ssl/quic/quic_tserver.c b/ssl/quic/quic_tserver.c index 96fb668b24..6795d4ec46 100644 --- a/ssl/quic/quic_tserver.c +++ b/ssl/quic/quic_tserver.c @@ -24,6 +24,12 @@ struct quic_tserver_st { */ QUIC_CHANNEL *ch; + /* SSL_CTX for creating the underlying TLS connection */ + SSL_CTX *ctx; + + /* SSL for the underlying TLS connection */ + SSL *tls; + /* Our single bidirectional application data stream. */ QUIC_STREAM *stream0; @@ -34,7 +40,21 @@ struct quic_tserver_st { unsigned int connected : 1; }; -QUIC_TSERVER *ossl_quic_tserver_new(const QUIC_TSERVER_ARGS *args) +static int alpn_select_cb(SSL *ssl, const unsigned char **out, + unsigned char *outlen, const unsigned char *in, + unsigned int inlen, void *arg) +{ + unsigned char alpn[] = { 8, 'o', 's', 's', 'l', 't', 'e', 's', 't' }; + + if (SSL_select_next_proto((unsigned char **)out, outlen, alpn, sizeof(alpn), + in, inlen) != OPENSSL_NPN_NEGOTIATED) + return SSL_TLSEXT_ERR_ALERT_FATAL; + + return SSL_TLSEXT_ERR_OK; +} + +QUIC_TSERVER *ossl_quic_tserver_new(const QUIC_TSERVER_ARGS *args, + const char *certfile, const char *keyfile) { QUIC_TSERVER *srv = NULL; QUIC_CHANNEL_ARGS ch_args = {0}; @@ -47,8 +67,25 @@ QUIC_TSERVER *ossl_quic_tserver_new(const QUIC_TSERVER_ARGS *args) srv->args = *args; + srv->ctx = SSL_CTX_new_ex(srv->args.libctx, srv->args.propq, TLS_method()); + if (srv->ctx == NULL) + goto err; + + if (SSL_CTX_use_certificate_file(srv->ctx, certfile, SSL_FILETYPE_PEM) <= 0) + goto err; + + if (SSL_CTX_use_PrivateKey_file(srv->ctx, keyfile, SSL_FILETYPE_PEM) <= 0) + goto err; + + SSL_CTX_set_alpn_select_cb(srv->ctx, alpn_select_cb, srv); + + srv->tls = SSL_new(srv->ctx); + if (srv->tls == NULL) + goto err; + ch_args.libctx = srv->args.libctx; ch_args.propq = srv->args.propq; + ch_args.tls = srv->tls; ch_args.is_server = 1; if ((srv->ch = ossl_quic_channel_new(&ch_args)) == NULL) @@ -80,6 +117,8 @@ void ossl_quic_tserver_free(QUIC_TSERVER *srv) ossl_quic_channel_free(srv->ch); BIO_free(srv->args.net_rbio); BIO_free(srv->args.net_wbio); + SSL_free(srv->tls); + SSL_CTX_free(srv->ctx); OPENSSL_free(srv); } |