summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2021-06-01 20:14:17 +0000
committertb <>2021-06-01 20:14:17 +0000
commit9e887183c2a90e6f5fe6b6767d78096483dd5345 (patch)
treeb6a01471dc4ae0b369c7831798a6388d9723e393
parentd9330d78516c910d1d1883d9da890f600bce7a02 (diff)
downloadopenbsd-9e887183c2a90e6f5fe6b6767d78096483dd5345.tar.gz
openbsd-9e887183c2a90e6f5fe6b6767d78096483dd5345.tar.bz2
openbsd-9e887183c2a90e6f5fe6b6767d78096483dd5345.zip
Avoid sending a trailing dot in SNI as a client
While an FQDN includes a trailing dot for the zero-length label of the root, SNI explicitly does not contain it. Contrary to other TLS implementations, our tlsext_sni_is_valid_hostname() rejects a trailing dot. The result is that LibreSSL TLS servers encountering an SNI with trailing dot abort the connection with an illegal_parameter alert. This fixes an issue reported by danj in nc(1) and by sthen in ftp(1). DNS cluebat from florian. ok jsing
-rw-r--r--src/lib/libtls/tls_client.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/src/lib/libtls/tls_client.c b/src/lib/libtls/tls_client.c
index 04e44020ef..701bb6fc81 100644
--- a/src/lib/libtls/tls_client.c
+++ b/src/lib/libtls/tls_client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_client.c,v 1.45 2018/03/19 16:34:47 jsing Exp $ */ 1/* $OpenBSD: tls_client.c,v 1.46 2021/06/01 20:14:17 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -279,6 +279,7 @@ static int
279tls_connect_common(struct tls *ctx, const char *servername) 279tls_connect_common(struct tls *ctx, const char *servername)
280{ 280{
281 union tls_addr addrbuf; 281 union tls_addr addrbuf;
282 size_t servername_len;
282 int rv = -1; 283 int rv = -1;
283 284
284 if ((ctx->flags & TLS_CLIENT) == 0) { 285 if ((ctx->flags & TLS_CLIENT) == 0) {
@@ -291,6 +292,17 @@ tls_connect_common(struct tls *ctx, const char *servername)
291 tls_set_errorx(ctx, "out of memory"); 292 tls_set_errorx(ctx, "out of memory");
292 goto err; 293 goto err;
293 } 294 }
295
296 /*
297 * If there's a trailing dot, remove it. While an FQDN includes
298 * the terminating dot representing the zero-length label of
299 * the root (RFC 8499, section 2), the SNI explicitly does not
300 * include it (RFC 6066, section 3).
301 */
302 servername_len = strlen(ctx->servername);
303 if (servername_len > 0 &&
304 ctx->servername[servername_len - 1] == '.')
305 ctx->servername[servername_len - 1] = '\0';
294 } 306 }
295 307
296 if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) { 308 if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) {
@@ -306,7 +318,7 @@ tls_connect_common(struct tls *ctx, const char *servername)
306 goto err; 318 goto err;
307 319
308 if (ctx->config->verify_name) { 320 if (ctx->config->verify_name) {
309 if (servername == NULL) { 321 if (ctx->servername == NULL) {
310 tls_set_errorx(ctx, "server name not specified"); 322 tls_set_errorx(ctx, "server name not specified");
311 goto err; 323 goto err;
312 } 324 }
@@ -353,10 +365,11 @@ tls_connect_common(struct tls *ctx, const char *servername)
353 * RFC4366 (SNI): Literal IPv4 and IPv6 addresses are not 365 * RFC4366 (SNI): Literal IPv4 and IPv6 addresses are not
354 * permitted in "HostName". 366 * permitted in "HostName".
355 */ 367 */
356 if (servername != NULL && 368 if (ctx->servername != NULL &&
357 inet_pton(AF_INET, servername, &addrbuf) != 1 && 369 inet_pton(AF_INET, ctx->servername, &addrbuf) != 1 &&
358 inet_pton(AF_INET6, servername, &addrbuf) != 1) { 370 inet_pton(AF_INET6, ctx->servername, &addrbuf) != 1) {
359 if (SSL_set_tlsext_host_name(ctx->ssl_conn, servername) == 0) { 371 if (SSL_set_tlsext_host_name(ctx->ssl_conn,
372 ctx->servername) == 0) {
360 tls_set_errorx(ctx, "server name indication failure"); 373 tls_set_errorx(ctx, "server name indication failure");
361 goto err; 374 goto err;
362 } 375 }