Browse Source

Make older TLS versions optional (#1693)

TLSv1 and TLSv1.1 can be enabled using `--tlsv1` and `--tlsv1_1`
arguments accordingly
That assumes openssl version being used has these versions enabled
(which as of openssl-3.5 is not by default)
Pavel Punsky 4 months ago
parent
commit
cc5e18fc89

+ 3 - 5
examples/etc/turnserver.conf

@@ -23,8 +23,8 @@
 # "automatically" recognizes the type of traffic. Actually, two listening
 # "automatically" recognizes the type of traffic. Actually, two listening
 # endpoints (the "plain" one and the "tls" one) are equivalent in terms of
 # endpoints (the "plain" one and the "tls" one) are equivalent in terms of
 # functionality; but Coturn keeps both endpoints to satisfy the RFC 5766 specs.
 # functionality; but Coturn keeps both endpoints to satisfy the RFC 5766 specs.
-# For secure TCP connections, Coturn currently supports SSL version 3 and
-# TLS version 1.0, 1.1 and 1.2.
+# For secure TCP connections, Coturn currently supports TLS version 1.2.
+# TLS 1.0 and TLS 1.1 are deprecated and need to be explicitly enabled.
 # For secure UDP connections, Coturn supports DTLS version 1.
 # For secure UDP connections, Coturn supports DTLS version 1.
 #
 #
 #tls-listening-port=5349
 #tls-listening-port=5349
@@ -328,7 +328,7 @@
 # This database can be used for the long-term credential mechanism
 # This database can be used for the long-term credential mechanism
 # and it can store the secret value for secret-based timed authentication in TURN REST API.
 # and it can store the secret value for secret-based timed authentication in TURN REST API.
 #
 #
-# Optional connection string parameters for the secure communications (SSL):
+# Optional connection string parameters for the secure communications (TLS):
 # ca, capath, cert, key, cipher
 # ca, capath, cert, key, cipher
 # (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the
 # (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the
 # command options description).
 # command options description).
@@ -795,8 +795,6 @@
 
 
 # Do not allow an TLS/DTLS version of protocol
 # Do not allow an TLS/DTLS version of protocol
 #
 #
-#no-tlsv1
-#no-tlsv1_1
 #no-tlsv1_2
 #no-tlsv1_2
 
 
 # Enable RFC5780 (NAT behavior discovery).
 # Enable RFC5780 (NAT behavior discovery).

+ 9 - 17
man/man1/turnserver.1

@@ -296,19 +296,16 @@ Use 566 bits predefined DH TLS key. Default size of the key is 2066.
 Use 1066 bits predefined DH TLS key. Default size of the key is 2066.
 Use 1066 bits predefined DH TLS key. Default size of the key is 2066.
 .TP
 .TP
 .B
 .B
-\fB\-\-no\-tlsv1\fP
-Set TLSv1_1/DTLSv1.2 as a minimum supported protocol version.
-With openssl\-1.0.2 and below, do not allow TLSv1.2/DTLSv1.2 protocols.
+\fB\-\-tlsv1\fP
+Set TLSv1 as a minimum supported protocol version.
 .TP
 .TP
 .B
 .B
-\fB\-\-no\-tlsv1_1\fP
-Set TLSv1_2/DTLSv1.2 as a minimum supported protocol version.
-With openssl\-1.0.2 and below, do not allow TLSv1.1 protocol.
+\fB\-\-tlsv1_1\fP
+Set TLSv1.1 as a minimum supported protocol version.
 .TP
 .TP
 .B
 .B
 \fB\-\-no\-tlsv1_2\fP
 \fB\-\-no\-tlsv1_2\fP
-Set TLSv1_3/DTLSv1.2 as a minimum supported protocol version.
-With openssl\-1.0.2 and below, do not allow TLSv1.2/DTLSv1.2 protocols.
+Set TLSv1_3 as a minimum supported protocol version.
 .TP
 .TP
 .B
 .B
 \fB\-\-no\-udp\fP
 \fB\-\-no\-udp\fP
@@ -504,8 +501,7 @@ Note: actually, "plain" TCP & UDP sessions can connect to the TLS & DTLS
 "automatically" recognizes the type of traffic. Actually, two listening
 "automatically" recognizes the type of traffic. Actually, two listening
 endpoints (the "plain" one and the "tls" one) are equivalent in terms of
 endpoints (the "plain" one and the "tls" one) are equivalent in terms of
 functionality; but we keep both endpoints to satisfy the RFC 5766 specs.
 functionality; but we keep both endpoints to satisfy the RFC 5766 specs.
-For secure TCP connections, we currently support SSL version 3 and
-TLS versions 1.0, 1.1, 1.2.
+For secure TCP connections, we currently TLS versions 1.2, 1.3
 For secure UDP connections, we support DTLS version 1.
 For secure UDP connections, we support DTLS version 1.
 .TP
 .TP
 .B
 .B
@@ -723,9 +719,6 @@ By default, no CA is set and no client certificate check is performed.
 \fB\-\-ec\-curve\-name\fP
 \fB\-\-ec\-curve\-name\fP
 Curve name for EC ciphers, if supported by OpenSSL
 Curve name for EC ciphers, if supported by OpenSSL
 library (TLS and DTLS). The default value is prime256v1,
 library (TLS and DTLS). The default value is prime256v1,
-if pre\-OpenSSL 1.0.2 is used. With OpenSSL 1.0.2+,
-an optimal curve will be automatically calculated, if not defined
-by this option.
 .TP
 .TP
 .B
 .B
 \fB\-\-dh\-file\fP
 \fB\-\-dh\-file\fP
@@ -1170,10 +1163,9 @@ location (/var/db/turndb or /usr/local/var/db/turndb or /var/lib/turn/turndb, de
 
 
 .SH ALPN
 .SH ALPN
 
 
-The server supports ALPNs "stun.turn" and "stun.nat\-discovery", when
-compiled with OpenSSL 1.0.2 or newer. If the server receives a TLS/DTLS
-ClientHello message that contains one or both of those ALPNs, then the
-server chooses the first stun.* label and sends it back (in the ServerHello)
+The server supports ALPNs "stun.turn" and "stun.nat\-discovery". If the server
+receives a TLS/DTLS ClientHello message that contains one or both of those ALPNs,
+then the server chooses the first stun.* label and sends it back (in the ServerHello)
 in the ALPN extension field. If no stun.* label is found, then the server
 in the ALPN extension field. If no stun.* label is found, then the server
 does not include the ALPN information into the ServerHello.
 does not include the ALPN information into the ServerHello.
 .SH =================================
 .SH =================================

+ 2 - 3
src/apps/common/apputils.h

@@ -63,9 +63,9 @@ extern int IS_TURN_SERVER;
 
 
 #if defined(TURN_NO_TLS)
 #if defined(TURN_NO_TLS)
 #define TLS_SUPPORTED 0
 #define TLS_SUPPORTED 0
-#else
+#else // ! defined(TURN_NO_TLS)
 #define TLS_SUPPORTED 1
 #define TLS_SUPPORTED 1
-#endif
+#endif // defined(TURN_NO_TLS)
 
 
 #if defined(TURN_NO_DTLS)
 #if defined(TURN_NO_DTLS)
 #define DTLS_SUPPORTED 0
 #define DTLS_SUPPORTED 0
@@ -80,7 +80,6 @@ extern int IS_TURN_SERVER;
 // clang-format off
 // clang-format off
 enum _TURN_TLS_TYPE {
 enum _TURN_TLS_TYPE {
   TURN_TLS_NO = 0,
   TURN_TLS_NO = 0,
-  TURN_TLS_SSL23,
   TURN_TLS_v1_0,
   TURN_TLS_v1_0,
   TURN_TLS_v1_1,
   TURN_TLS_v1_1,
   TURN_TLS_v1_2,
   TURN_TLS_v1_2,

+ 29 - 23
src/apps/relay/mainrelay.c

@@ -95,8 +95,8 @@ turn_params_t turn_params = {
     "",                     /*tls_password*/
     "",                     /*tls_password*/
     "",                     /*dh_file*/
     "",                     /*dh_file*/
 
 
-    false, /*no_tlsv1*/
-    false, /*no_tlsv1_1*/
+    false, /*enable_tlsv1*/
+    false, /*enable_tlsv1_1*/
     false, /*no_tlsv1_2*/
     false, /*no_tlsv1_2*/
            /*no_tls*/
            /*no_tls*/
 #if !TLS_SUPPORTED
 #if !TLS_SUPPORTED
@@ -1192,12 +1192,8 @@ static char Usage[] =
     " --dh-file	<dh-file-name>			Use custom DH TLS key, stored in PEM format in the file.\n"
     " --dh-file	<dh-file-name>			Use custom DH TLS key, stored in PEM format in the file.\n"
     "						Flags --dh566 and --dh1066 are ignored when the DH key is taken from a "
     "						Flags --dh566 and --dh1066 are ignored when the DH key is taken from a "
     "file.\n"
     "file.\n"
-    " --no-tlsv1					Set TLSv1.1/DTLSv1.2 as a minimum supported protocol version.\n"
-    "						With openssl-1.0.2 and below, do not allow "
-    "TLSv1/DTLSv1 protocols.\n"
-    " --no-tlsv1_1					Set TLSv1.2/DTLSv1.2 as a minimum supported protocol version.\n"
-    "						With openssl-1.0.2 and below, do not allow TLSv1.1 "
-    "protocol.\n"
+    " --tlsv1					Set TLSv1 as a minimum supported protocol version.\n"
+    " --tlsv1_1					Set TLSv1.1 as a minimum supported protocol version.\n"
     " --no-tlsv1_2					Set TLSv1.3/DTLSv1.2 as a minimum supported protocol version.\n"
     " --no-tlsv1_2					Set TLSv1.3/DTLSv1.2 as a minimum supported protocol version.\n"
     "						With openssl-1.0.2 and below, do not allow "
     "						With openssl-1.0.2 and below, do not allow "
     "TLSv1.2/DTLSv1.2 protocols.\n"
     "TLSv1.2/DTLSv1.2 protocols.\n"
@@ -1482,8 +1478,8 @@ enum EXTRA_OPTS {
   DH566_OPT,
   DH566_OPT,
   DH1066_OPT,
   DH1066_OPT,
   NE_TYPE_OPT,
   NE_TYPE_OPT,
-  NO_TLSV1_OPT,
-  NO_TLSV1_1_OPT,
+  ENABLE_TLSV1_OPT,
+  ENABLE_TLSV1_1_OPT,
   NO_TLSV1_2_OPT,
   NO_TLSV1_2_OPT,
   CHECK_ORIGIN_CONSISTENCY_OPT,
   CHECK_ORIGIN_CONSISTENCY_OPT,
   ADMIN_MAX_BPS_OPT,
   ADMIN_MAX_BPS_OPT,
@@ -1633,8 +1629,8 @@ static const struct myoption long_options[] = {
     {"dh566", optional_argument, NULL, DH566_OPT},
     {"dh566", optional_argument, NULL, DH566_OPT},
     {"dh1066", optional_argument, NULL, DH1066_OPT},
     {"dh1066", optional_argument, NULL, DH1066_OPT},
     {"ne", required_argument, NULL, NE_TYPE_OPT},
     {"ne", required_argument, NULL, NE_TYPE_OPT},
-    {"no-tlsv1", optional_argument, NULL, NO_TLSV1_OPT},
-    {"no-tlsv1_1", optional_argument, NULL, NO_TLSV1_1_OPT},
+    {"tlsv1", optional_argument, NULL, ENABLE_TLSV1_OPT},
+    {"tlsv1_1", optional_argument, NULL, ENABLE_TLSV1_1_OPT},
     {"no-tlsv1_2", optional_argument, NULL, NO_TLSV1_2_OPT},
     {"no-tlsv1_2", optional_argument, NULL, NO_TLSV1_2_OPT},
     {"secret-key-file", required_argument, NULL, SECRET_KEY_OPT},
     {"secret-key-file", required_argument, NULL, SECRET_KEY_OPT},
     {"keep-address-family", optional_argument, NULL, 'K'},
     {"keep-address-family", optional_argument, NULL, 'K'},
@@ -1908,11 +1904,11 @@ static void set_option(int c, char *value) {
       turn_params.oauth = get_bool_value(value);
       turn_params.oauth = get_bool_value(value);
     }
     }
     break;
     break;
-  case NO_TLSV1_OPT:
-    turn_params.no_tlsv1 = get_bool_value(value);
+  case ENABLE_TLSV1_OPT:
+    turn_params.enable_tlsv1 = get_bool_value(value);
     break;
     break;
-  case NO_TLSV1_1_OPT:
-    turn_params.no_tlsv1_1 = get_bool_value(value);
+  case ENABLE_TLSV1_1_OPT:
+    turn_params.enable_tlsv1_1 = get_bool_value(value);
     break;
     break;
   case NO_TLSV1_2_OPT:
   case NO_TLSV1_2_OPT:
     turn_params.no_tlsv1_2 = get_bool_value(value);
     turn_params.no_tlsv1_2 = get_bool_value(value);
@@ -2815,6 +2811,15 @@ static void print_features(unsigned long mfn) {
 #if !TLS_SUPPORTED
 #if !TLS_SUPPORTED
   TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS is not supported\n");
   TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS is not supported\n");
 #else
 #else
+  if (turn_params.enable_tlsv1) {
+    TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS 1 supported\n");
+  }
+  if (turn_params.enable_tlsv1_1) {
+    TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS 1.1 supported\n");
+  }
+  if (!turn_params.no_tlsv1_2) {
+    TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS 1.2 supported\n");
+  }
   TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS 1.3 supported\n");
   TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS 1.3 supported\n");
 #endif
 #endif
 
 
@@ -3792,17 +3797,21 @@ static void openssl_load_certificates(void) {
 
 
   TURN_MUTEX_LOCK(&turn_params.tls_mutex);
   TURN_MUTEX_LOCK(&turn_params.tls_mutex);
   if (!turn_params.no_tls) {
   if (!turn_params.no_tls) {
+#if !TLS_SUPPORTED
+    TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: TLS is not supported.\n");
+#else
     set_ctx(&turn_params.tls_ctx, "TLS", TLS_server_method());
     set_ctx(&turn_params.tls_ctx, "TLS", TLS_server_method());
-    if (turn_params.no_tlsv1) {
-      SSL_CTX_set_min_proto_version(turn_params.tls_ctx, TLS1_1_VERSION);
+    if (turn_params.enable_tlsv1) {
+      SSL_CTX_set_min_proto_version(turn_params.tls_ctx, TLS1_VERSION);
     }
     }
-    if (turn_params.no_tlsv1_1) {
-      SSL_CTX_set_min_proto_version(turn_params.tls_ctx, TLS1_2_VERSION);
+    if (turn_params.enable_tlsv1_1) {
+      SSL_CTX_set_min_proto_version(turn_params.tls_ctx, TLS1_1_VERSION);
     }
     }
     if (turn_params.no_tlsv1_2) {
     if (turn_params.no_tlsv1_2) {
       SSL_CTX_set_min_proto_version(turn_params.tls_ctx, TLS1_3_VERSION);
       SSL_CTX_set_min_proto_version(turn_params.tls_ctx, TLS1_3_VERSION);
     }
     }
     TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS cipher suite: %s\n", turn_params.cipher_list);
     TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS cipher suite: %s\n", turn_params.cipher_list);
+#endif
   }
   }
 
 
   if (!turn_params.no_dtls) {
   if (!turn_params.no_dtls) {
@@ -3810,9 +3819,6 @@ static void openssl_load_certificates(void) {
     TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: DTLS is not supported.\n");
     TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: DTLS is not supported.\n");
 #else
 #else
     set_ctx(&turn_params.dtls_ctx, "DTLS", DTLS_server_method());
     set_ctx(&turn_params.dtls_ctx, "DTLS", DTLS_server_method());
-    if (turn_params.no_tlsv1 || turn_params.no_tlsv1_1) {
-      SSL_CTX_set_min_proto_version(turn_params.dtls_ctx, DTLS1_2_VERSION);
-    }
     if (turn_params.no_tlsv1_2) {
     if (turn_params.no_tlsv1_2) {
       SSL_CTX_set_max_proto_version(turn_params.dtls_ctx, DTLS1_VERSION);
       SSL_CTX_set_max_proto_version(turn_params.dtls_ctx, DTLS1_VERSION);
     }
     }

+ 7 - 5
src/apps/relay/mainrelay.h

@@ -107,13 +107,15 @@ extern "C" {
 
 
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
 #define DEFAULT_CIPHER_LIST OSSL_default_cipher_list()
 #define DEFAULT_CIPHER_LIST OSSL_default_cipher_list()
+#if TLS_SUPPORTED
 #define DEFAULT_CIPHERSUITES OSSL_default_ciphersuites()
 #define DEFAULT_CIPHERSUITES OSSL_default_ciphersuites()
-#else
+#endif
+#else // OPENSSL_VERSION_NUMBER < 0x30000000L
 #define DEFAULT_CIPHER_LIST "DEFAULT"
 #define DEFAULT_CIPHER_LIST "DEFAULT"
-#if defined(TLS_DEFAULT_CIPHERSUITES)
+#if TLS_SUPPORTED && defined(TLS_DEFAULT_CIPHERSUITES)
 #define DEFAULT_CIPHERSUITES TLS_DEFAULT_CIPHERSUITES
 #define DEFAULT_CIPHERSUITES TLS_DEFAULT_CIPHERSUITES
 #endif
 #endif
-#endif
+#endif // OPENSSL_VERSION_NUMBER >= 0x30000000L
 
 
 #define DEFAULT_EC_CURVE_NAME "prime256v1"
 #define DEFAULT_EC_CURVE_NAME "prime256v1"
 
 
@@ -197,8 +199,8 @@ typedef struct _turn_params_ {
   char tls_password[513];
   char tls_password[513];
   char dh_file[1025];
   char dh_file[1025];
 
 
-  bool no_tlsv1;
-  bool no_tlsv1_1;
+  bool enable_tlsv1;
+  bool enable_tlsv1_1;
   bool no_tlsv1_2;
   bool no_tlsv1_2;
   bool no_tls;
   bool no_tls;
   bool no_dtls;
   bool no_dtls;

+ 2 - 2
src/apps/relay/ns_ioalib_engine_impl.c

@@ -2145,12 +2145,12 @@ static TURN_TLS_TYPE check_tentative_tls(ioa_socket_raw fd) {
     if ((s[0] == 22) && (s[1] == 3) && (s[5] == 1) && (s[9] == 3)) {
     if ((s[0] == 22) && (s[1] == 3) && (s[5] == 1) && (s[9] == 3)) {
       char max_supported = (char)(TURN_TLS_TOTAL - 2);
       char max_supported = (char)(TURN_TLS_TOTAL - 2);
       if (s[10] > max_supported) {
       if (s[10] > max_supported) {
-        ret = TURN_TLS_SSL23; /* compatibility mode */
+        ret = TURN_TLS_v1_2; /* compatibility mode */
       } else {
       } else {
         ret = (TURN_TLS_TYPE)(s[10] + 1);
         ret = (TURN_TLS_TYPE)(s[10] + 1);
       }
       }
     } else if ((s[2] == 1) && (s[3] == 3)) {
     } else if ((s[2] == 1) && (s[3] == 3)) {
-      ret = TURN_TLS_SSL23; /* compatibility mode */
+      ret = TURN_TLS_v1_2; /* compatibility mode */
     }
     }
   }
   }
 
 

+ 2 - 4
src/apps/relay/turn_admin_server.c

@@ -749,8 +749,8 @@ static void cli_print_configuration(struct cli_session *cs) {
     cli_print_flag(cs, turn_params.no_dtls, "no-dtls", 0);
     cli_print_flag(cs, turn_params.no_dtls, "no-dtls", 0);
     cli_print_flag(cs, turn_params.no_tls, "no-tls", 0);
     cli_print_flag(cs, turn_params.no_tls, "no-tls", 0);
 
 
-    cli_print_flag(cs, (!turn_params.no_tlsv1 && !turn_params.no_tls), "TLSv1.0", 0);
-    cli_print_flag(cs, (!turn_params.no_tlsv1_1 && !turn_params.no_tls), "TLSv1.1", 0);
+    cli_print_flag(cs, (turn_params.enable_tlsv1 && !turn_params.no_tls), "TLSv1.0", 0);
+    cli_print_flag(cs, (turn_params.enable_tlsv1_1 && !turn_params.no_tls), "TLSv1.1", 0);
     cli_print_flag(cs, (!turn_params.no_tlsv1_2 && !turn_params.no_tls), "TLSv1.2", 0);
     cli_print_flag(cs, (!turn_params.no_tlsv1_2 && !turn_params.no_tls), "TLSv1.2", 0);
 
 
     cli_print_uint(cs, (unsigned long)turn_params.listener_port, "listener-port", 0);
     cli_print_uint(cs, (unsigned long)turn_params.listener_port, "listener-port", 0);
@@ -2139,8 +2139,6 @@ static void write_pc_page(ioa_socket_handle s) {
         https_print_flag(sb, turn_params.no_dtls, "no-dtls", 0);
         https_print_flag(sb, turn_params.no_dtls, "no-dtls", 0);
         https_print_flag(sb, turn_params.no_tls, "no-tls", 0);
         https_print_flag(sb, turn_params.no_tls, "no-tls", 0);
 
 
-        https_print_flag(sb, (!turn_params.no_tlsv1 && !turn_params.no_tls), "TLSv1.0", 0);
-        https_print_flag(sb, (!turn_params.no_tlsv1_1 && !turn_params.no_tls), "TLSv1.1", 0);
         https_print_flag(sb, (!turn_params.no_tlsv1_2 && !turn_params.no_tls), "TLSv1.2", 0);
         https_print_flag(sb, (!turn_params.no_tlsv1_2 && !turn_params.no_tls), "TLSv1.2", 0);
 
 
         https_print_uint(sb, (unsigned long)turn_params.listener_port, "listener-port", 0);
         https_print_uint(sb, (unsigned long)turn_params.listener_port, "listener-port", 0);