[openssl] OpenSSL_1_1_1-stable update

Matt Caswell matt at openssl.org
Tue Feb 19 17:36:54 UTC 2019


The branch OpenSSL_1_1_1-stable has been updated
       via  70fa3aa108320d15536228656b120d3e08de0e40 (commit)
      from  663dc8c133e102950af9ad907fc19e123aabdc76 (commit)


- Log -----------------------------------------------------------------
commit 70fa3aa108320d15536228656b120d3e08de0e40
Author: Ionut Mihalcea <ionut.mihalcea at sophos.com>
Date:   Wed Feb 6 21:09:15 2019 +0000

    Don't set SNI by default if hostname is not dNS name
    
    Reviewed-by: Ben Kaduk <kaduk at mit.edu>
    Reviewed-by: Viktor Dukhovni <viktor at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/8175)
    
    (cherry picked from commit 8e981051ceecd10754f8f6d1291414a7453c8fac)

-----------------------------------------------------------------------

Summary of changes:
 apps/s_client.c       | 76 ++++++++++++++++++++++++++++++++++++++++++++++++---
 doc/man1/s_client.pod | 19 +++++++------
 2 files changed, 83 insertions(+), 12 deletions(-)

diff --git a/apps/s_client.c b/apps/s_client.c
index 4eb865a..4dd6e2f 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright 2005 Nokia. All rights reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
@@ -74,6 +74,7 @@ static void print_stuff(BIO *berr, SSL *con, int full);
 static int ocsp_resp_cb(SSL *s, void *arg);
 #endif
 static int ldap_ExtendedResponse_parse(const char *buf, long rem);
+static int is_dNS_name(const char *host);
 
 static int saved_errno;
 
@@ -1991,9 +1992,11 @@ int s_client_main(int argc, char **argv)
         SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
 
     if (!noservername && (servername != NULL || dane_tlsa_domain == NULL)) {
-        if (servername == NULL)
-            servername = (host == NULL) ? "localhost" : host;
-        if (!SSL_set_tlsext_host_name(con, servername)) {
+        if (servername == NULL) {
+            if(host == NULL || is_dNS_name(host)) 
+                servername = (host == NULL) ? "localhost" : host;
+        }
+        if (servername != NULL && !SSL_set_tlsext_host_name(con, servername)) {
             BIO_printf(bio_err, "Unable to set TLS servername extension.\n");
             ERR_print_errors(bio_err);
             goto end;
@@ -3473,4 +3476,69 @@ static int ldap_ExtendedResponse_parse(const char *buf, long rem)
     return ret;
 }
 
+/*
+ * Host dNS Name verifier: used for checking that the hostname is in dNS format 
+ * before setting it as SNI
+ */
+static int is_dNS_name(const char *host)
+{
+    const size_t MAX_LABEL_LENGTH = 63;
+    size_t i;
+    int isdnsname = 0;
+    size_t length = strlen(host);
+    size_t label_length = 0;
+    int all_numeric = 1;
+
+    /*
+     * Deviation from strict DNS name syntax, also check names with '_'
+     * Check DNS name syntax, any '-' or '.' must be internal,
+     * and on either side of each '.' we can't have a '-' or '.'.
+     *
+     * If the name has just one label, we don't consider it a DNS name.
+     */
+    for (i = 0; i < length && label_length < MAX_LABEL_LENGTH; ++i) {
+        char c = host[i];
+
+        if ((c >= 'a' && c <= 'z')
+            || (c >= 'A' && c <= 'Z')
+            || c == '_') {
+            label_length += 1;
+            all_numeric = 0;
+            continue;
+        }
+
+        if (c >= '0' && c <= '9') {
+            label_length += 1;
+            continue;
+        }
+
+        /* Dot and hyphen cannot be first or last. */
+        if (i > 0 && i < length - 1) {
+            if (c == '-') {
+                label_length += 1;
+                continue;
+            }
+            /*
+             * Next to a dot the preceding and following characters must not be
+             * another dot or a hyphen.  Otherwise, record that the name is
+             * plausible, since it has two or more labels.
+             */
+            if (c == '.'
+                && host[i + 1] != '.'
+                && host[i - 1] != '-'
+                && host[i + 1] != '-') {
+                label_length = 0;
+                isdnsname = 1;
+                continue;
+            }
+        }
+        isdnsname = 0;
+        break;
+    }
+
+    /* dNS name must not be all numeric and labels must be shorter than 64 characters. */
+    isdnsname &= !all_numeric && !(label_length == MAX_LABEL_LENGTH);
+
+    return isdnsname;
+}
 #endif                          /* OPENSSL_NO_SOCK */
diff --git a/doc/man1/s_client.pod b/doc/man1/s_client.pod
index 58fe37a..0f54ee1 100644
--- a/doc/man1/s_client.pod
+++ b/doc/man1/s_client.pod
@@ -191,14 +191,17 @@ Use IPv6 only.
 =item B<-servername name>
 
 Set the TLS SNI (Server Name Indication) extension in the ClientHello message to
-the given value. If both this option and the B<-noservername> are not given, the
-TLS SNI extension is still set to the hostname provided to the B<-connect> option,
-or "localhost" if B<-connect> has not been supplied. This is default since OpenSSL
-1.1.1.
-
-Even though SNI name should normally be a DNS name and not an IP address, this
-option will not make the distinction when parsing B<-connect> and will send
-IP address if one passed.
+the given value. 
+If B<-servername> is not provided, the TLS SNI extension will be populated with 
+the name given to B<-connect> if it follows a DNS name format. If B<-connect> is 
+not provided either, the SNI is set to "localhost".
+This is the default since OpenSSL 1.1.1.
+
+Even though SNI should normally be a DNS name and not an IP address, if 
+B<-servername> is provided then that name will be sent, regardless of whether 
+it is a DNS name or not.
+
+This option cannot be used in conjuction with B<-noservername>.
 
 =item B<-noservername>
 


More information about the openssl-commits mailing list