This diff look like a lot has changed, but this just adds some ifs to check
for NULL in tls_ctx_restrict_ciphers() to prepare for disabling export
ciphers by default in OpenVPN 2.4+.

Signed-off-by: Steffan Karger <stef...@karger.me>
---
 src/openvpn/ssl.c          |   5 +-
 src/openvpn/ssl_backend.h  |   5 +-
 src/openvpn/ssl_openssl.c  | 130 ++++++++++++++++++++++++++-------------------
 src/openvpn/ssl_polarssl.c |   7 ++-
 4 files changed, 85 insertions(+), 62 deletions(-)

diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index bd19d75..93222c4 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -543,10 +543,7 @@ init_ssl (const struct options *options, struct 
tls_root_ctx *new_ctx)
     }

   /* Allowable ciphers */
-  if (options->cipher_list)
-    {
-      tls_ctx_restrict_ciphers(new_ctx, options->cipher_list);
-    }
+  tls_ctx_restrict_ciphers(new_ctx, options->cipher_list);

 #ifdef ENABLE_CRYPTO_POLARSSL
   /* Personalise the random by mixing in the certificate */
diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h
index 54383fe..a6fc3bd 100644
--- a/src/openvpn/ssl_backend.h
+++ b/src/openvpn/ssl_backend.h
@@ -167,8 +167,9 @@ void tls_ctx_set_options (struct tls_root_ctx *ctx, 
unsigned int ssl_flags);
 /**
  * Restrict the list of ciphers that can be used within the TLS context.
  *
- * @param ctx          TLS context to restrict
- * @param ciphers      String containing : delimited cipher names.
+ * @param ctx          TLS context to restrict, must be valid.
+ * @param ciphers      String containing : delimited cipher names, or NULL to 
use
+ *                                     sane defaults.
  */
 void tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers);

diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index 08327a1..5f6c270 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -217,71 +217,91 @@ tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned 
int ssl_flags)
 void
 tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
 {
-  size_t begin_of_cipher, end_of_cipher;
-
-  const char *current_cipher;
-  size_t current_cipher_len;
+  if (ciphers == NULL)
+    {
+      /* Nothing to do */
+      return;
+    }
+  else
+    {
+      /* Parse supplied cipher list and pass on to OpenSSL */
+      size_t begin_of_cipher, end_of_cipher;

-  const tls_cipher_name_pair *cipher_pair;
+      const char *current_cipher;
+      size_t current_cipher_len;

-  char openssl_ciphers[4096];
-  size_t openssl_ciphers_len = 0;
-  openssl_ciphers[0] = '\0';
+      const tls_cipher_name_pair *cipher_pair;

-  ASSERT(NULL != ctx);
+      char openssl_ciphers[4096];
+      size_t openssl_ciphers_len = 0;
+      openssl_ciphers[0] = '\0';

-  // Translate IANA cipher suite names to OpenSSL names
-  begin_of_cipher = end_of_cipher = 0;
-  for (; begin_of_cipher < strlen(ciphers); begin_of_cipher = end_of_cipher) {
-      end_of_cipher += strcspn(&ciphers[begin_of_cipher], ":");
-      cipher_pair = tls_get_cipher_name_pair(&ciphers[begin_of_cipher], 
end_of_cipher - begin_of_cipher);
+      ASSERT(NULL != ctx);

-      if (NULL == cipher_pair)
+      // Translate IANA cipher suite names to OpenSSL names
+      begin_of_cipher = end_of_cipher = 0;
+      for (; begin_of_cipher < strlen(ciphers); begin_of_cipher = 
end_of_cipher)
         {
-          // No translation found, use original
-          current_cipher = &ciphers[begin_of_cipher];
-          current_cipher_len = end_of_cipher - begin_of_cipher;
-
-          // Issue warning on missing translation
-          // %.*s format specifier expects length of type int, so guarantee
-          // that length is small enough and cast to int.
-          msg (M_WARN, "No valid translation found for TLS cipher '%.*s'",
-                 constrain_int(current_cipher_len, 0, 256), current_cipher);
-        }
-      else
-       {
-         // Use OpenSSL name
-          current_cipher = cipher_pair->openssl_name;
-          current_cipher_len = strlen(current_cipher);
-
-         if (end_of_cipher - begin_of_cipher == current_cipher_len &&
-             0 == memcmp (&ciphers[begin_of_cipher], 
cipher_pair->openssl_name, end_of_cipher - begin_of_cipher))
-           {
-             // Non-IANA name used, show warning
-             msg (M_WARN, "Deprecated TLS cipher name '%s', please use IANA 
name '%s'", cipher_pair->openssl_name, cipher_pair->iana_name);
-           }
-       }
-
-      // Make sure new cipher name fits in cipher string
-      if (((sizeof(openssl_ciphers)-1) - openssl_ciphers_len) < 
current_cipher_len) {
-       msg(M_SSLERR, "Failed to set restricted TLS cipher list, too long 
(>%d).", (int)sizeof(openssl_ciphers)-1);
-      }
+          end_of_cipher += strcspn(&ciphers[begin_of_cipher], ":");
+          cipher_pair = tls_get_cipher_name_pair(&ciphers[begin_of_cipher],
+              end_of_cipher - begin_of_cipher);

-      // Concatenate cipher name to OpenSSL cipher string
-      memcpy(&openssl_ciphers[openssl_ciphers_len], current_cipher, 
current_cipher_len);
-      openssl_ciphers_len += current_cipher_len;
-      openssl_ciphers[openssl_ciphers_len] = ':';
-      openssl_ciphers_len++;
+          if (NULL == cipher_pair)
+            {
+              // No translation found, use original
+              current_cipher = &ciphers[begin_of_cipher];
+              current_cipher_len = end_of_cipher - begin_of_cipher;
+
+              // Issue warning on missing translation
+              // %.*s format specifier expects length of type int, so guarantee
+              // that length is small enough and cast to int.
+              msg (M_WARN, "No valid translation found for TLS cipher '%.*s'",
+                     constrain_int(current_cipher_len, 0, 256), 
current_cipher);
+            }
+          else
+            {
+              // Use OpenSSL name
+              current_cipher = cipher_pair->openssl_name;
+              current_cipher_len = strlen(current_cipher);
+
+              if (end_of_cipher - begin_of_cipher == current_cipher_len &&
+                  0 == memcmp (&ciphers[begin_of_cipher],
+                      cipher_pair->openssl_name,
+                      end_of_cipher - begin_of_cipher))
+                {
+                  // Non-IANA name used, show warning
+                  msg (M_WARN, "Deprecated TLS cipher name '%s', "
+                      "please use IANA name '%s'", cipher_pair->openssl_name,
+                      cipher_pair->iana_name);
+                }
+            }

-      end_of_cipher++;
-  }
+          // Make sure new cipher name fits in cipher string
+          if (((sizeof(openssl_ciphers)-1) - openssl_ciphers_len) <
+              current_cipher_len) {
+            msg(M_SSLERR,
+                "Failed to set restricted TLS cipher list, too long (>%d).",
+                (int)sizeof(openssl_ciphers)-1);
+          }
+
+          // Concatenate cipher name to OpenSSL cipher string
+          memcpy(&openssl_ciphers[openssl_ciphers_len], current_cipher,
+              current_cipher_len);
+          openssl_ciphers_len += current_cipher_len;
+          openssl_ciphers[openssl_ciphers_len] = ':';
+          openssl_ciphers_len++;
+
+          end_of_cipher++;
+        }

-  if (openssl_ciphers_len > 0)
-    openssl_ciphers[openssl_ciphers_len-1] = '\0';
+      if (openssl_ciphers_len > 0)
+        openssl_ciphers[openssl_ciphers_len-1] = '\0';

-  // Set OpenSSL cipher list
-  if(!SSL_CTX_set_cipher_list(ctx->ctx, openssl_ciphers))
-    msg(M_SSLERR, "Failed to set restricted TLS cipher list: %s", 
openssl_ciphers);
+      // Set OpenSSL cipher list
+      if(!SSL_CTX_set_cipher_list(ctx->ctx, openssl_ciphers))
+        msg(M_SSLERR, "Failed to set restricted TLS cipher list: %s",
+            openssl_ciphers);
+    }
 }

 void
diff --git a/src/openvpn/ssl_polarssl.c b/src/openvpn/ssl_polarssl.c
index 551c352..d964b91 100644
--- a/src/openvpn/ssl_polarssl.c
+++ b/src/openvpn/ssl_polarssl.c
@@ -173,7 +173,12 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const 
char *ciphers)
 {
   char *tmp_ciphers, *tmp_ciphers_orig, *token;
   int i, cipher_count;
-  int ciphers_len = strlen (ciphers);
+  int ciphers_len;
+
+  if (NULL == ciphers)
+    return; // Nothing to do
+
+  ciphers_len = strlen (ciphers);

   ASSERT (NULL != ctx);
   ASSERT (0 != ciphers_len);
-- 
1.8.3.2


Reply via email to