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;
 

Reply via email to