summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2022-11-29 11:26:08 +0000
committerMatt Caswell <matt@openssl.org>2023-01-24 17:16:29 +0000
commit4e3a55fd14cb4424fd62516345d918cdf0d9cdcc (patch)
tree34182d4cac374cde52a242d1b04ea14c2f02d59d /ssl
parentc28f1a8bb9ccfecb76bcf3b7987e2a526b427bca (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.c2
-rw-r--r--ssl/quic/quic_tls.c30
-rw-r--r--ssl/quic/quic_tserver.c41
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);
}