On Sun, May 30, 2021 at 02:31:55PM -0000, Stuart Henderson wrote: > On 2021-05-30, Theo Buehler <t...@theobuehler.org> wrote: > > On Sat, May 29, 2021 at 10:37:18PM -0400, Daniel Jakots wrote: > >> Hi, > >> > >> $ nc -zvc openbsd.org 443 # works as expected > >> Connection to openbsd.org (129.128.5.194) 443 port [tcp/https] succeeded! > >> TLS handshake negotiated TLSv1.3/AEAD-AES256-GCM-SHA384 with host > >> openbsd.org > >> [...] > >> > >> $ nc -zvc openbsd.org. 443 # fails > >> Connection to openbsd.org. (129.128.5.194) 443 port [tcp/https] succeeded! > >> nc: tls handshake failed (handshake failed: error:1404B42E:SSL > >> routines:ST_CONNECT:tlsv1 alert protocol version) > > > > $ nc -cvz -e openbsd.org openbsd.org. 443 # works > > > > Unless -e is given, nc uses 'destination' in its server name indication > > (SNI) extension. By its specification, (RFC 6066, section 3) the SNI > > does not contain the trailing dot. > > Should something (libtls perhaps; ftp(1) is affected too) strip the dot? > curl does handle this. >
Unsure. If people really think this is useful and necessary, I can be convinced. It's easy enough to do. And you're right, curl strips the trailing dot after resolving a host name for SNI and HTTP host header. I would be against doing it server side since contrary to sending IP addresses it doesn't seem to be common, but doing this client side seems innocuous. Index: tls_client.c =================================================================== RCS file: /cvs/src/lib/libtls/tls_client.c,v retrieving revision 1.45 diff -u -p -r1.45 tls_client.c --- tls_client.c 19 Mar 2018 16:34:47 -0000 1.45 +++ tls_client.c 30 May 2021 15:26:54 -0000 @@ -279,6 +279,7 @@ static int tls_connect_common(struct tls *ctx, const char *servername) { union tls_addr addrbuf; + size_t servername_len; int rv = -1; if ((ctx->flags & TLS_CLIENT) == 0) { @@ -291,6 +292,12 @@ tls_connect_common(struct tls *ctx, cons tls_set_errorx(ctx, "out of memory"); goto err; } + + /* If there's a trailing dot, strip it. */ + servername_len = strlen(servername); + if (servername_len > 0 && + ctx->servername[servername_len - 1] == '.') + ctx->servername[servername_len - 1] = '\0'; } if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) { @@ -306,7 +313,7 @@ tls_connect_common(struct tls *ctx, cons goto err; if (ctx->config->verify_name) { - if (servername == NULL) { + if (ctx->servername == NULL) { tls_set_errorx(ctx, "server name not specified"); goto err; } @@ -353,10 +360,11 @@ tls_connect_common(struct tls *ctx, cons * RFC4366 (SNI): Literal IPv4 and IPv6 addresses are not * permitted in "HostName". */ - if (servername != NULL && - inet_pton(AF_INET, servername, &addrbuf) != 1 && - inet_pton(AF_INET6, servername, &addrbuf) != 1) { - if (SSL_set_tlsext_host_name(ctx->ssl_conn, servername) == 0) { + if (ctx->servername != NULL && + inet_pton(AF_INET, ctx->servername, &addrbuf) != 1 && + inet_pton(AF_INET6, ctx->servername, &addrbuf) != 1) { + if (SSL_set_tlsext_host_name(ctx->ssl_conn, + ctx->servername) == 0) { tls_set_errorx(ctx, "server name indication failure"); goto err; } Index: tls_server.c =================================================================== RCS file: /cvs/src/lib/libtls/tls_server.c,v retrieving revision 1.45 diff -u -p -r1.45 tls_server.c --- tls_server.c 13 May 2019 22:36:01 -0000 1.45 +++ tls_server.c 30 May 2021 15:28:10 -0000 @@ -109,7 +109,7 @@ tls_servername_cb(SSL *ssl, int *al, voi inet_pton(AF_INET6, name, &addrbuf) == 1) return (SSL_TLSEXT_ERR_NOACK); - free((char *)conn_ctx->servername); + free(conn_ctx->servername); if ((conn_ctx->servername = strdup(name)) == NULL) goto err;