Browse code

TLS version negotiation

Updated the TLS negotiation logic to adaptively try to connect using
the highest TLS version supported by both client and server.
Previously, OpenVPN (when linked with OpenSSL) would always connect
using TLS 1.0.

Also added tls-version-min directive to force a higher TLS version
than 1.0:

tls-version-min <version> ['or-highest'] -- sets the minimum
TLS version we will accept from the peer. Examples for version
include "1.0" (default), "1.1", or "1.2". If 'or-highest' is
specified and version is not recognized, we will only accept
the highest TLS version supported by the local SSL implementation.

Examples:

tls-version-min 1.1 -- fail the connection unless peer can
connect at TLS 1.1 or higher.

tls-version-min 1.2 or-highest -- require that the peer
connect at TLS 1.2 or higher, however if the local SSL
implementation doesn't support TLS 1.2 (as it wouldn't
if linked with an older version of OpenSSL), reduce the
minimum required version to the highest version supported
by the local SSL implementation (such as TLS 1.0). This
is intended to allow client configurations to target higher
TLS versions that are supported on the server, even if some
older clients don't support these versions yet.

[
This is a merged patch from on the following commits
on git://github.com/jamesyonan/openvpn.git

03a5599202bdc3ba07983dc4efdae387fb8fb436
d23005413b0e0f28a3c48a6342f494763d5c9b40
]

Signed-off-by: James Yonan <james@openvpn.net>
Acked-by: Gert Doering <gert@greenie.muc.de>
Acked-by: Arne Schwabe <arne@rfc2549.org>
URL: http://thread.gmane.org/gmane.network.openvpn.devel/7743
URL: http://thread.gmane.org/gmane.network.openvpn.devel/7744
Message-Id: 51C77F12.1090802@openvpn.net
Signed-off-by: David Sommerseth <davids@redhat.com>

James Yonan authored on 2013/06/11 13:59:30
Showing 7 changed files
... ...
@@ -4246,6 +4246,15 @@ when you built your peer's certificate (see
4246 4246
 above).
4247 4247
 .\"*********************************************************
4248 4248
 .TP
4249
+.B \-\-tls-version-min version ['or-highest']
4250
+Sets the minimum
4251
+TLS version we will accept from the peer (default is "1.0").
4252
+Examples for version
4253
+include "1.0", "1.1", or "1.2".  If 'or-highest' is specified
4254
+and version is not recognized, we will only accept the highest TLS
4255
+version supported by the local SSL implementation.
4256
+.\"*********************************************************
4257
+.TP
4249 4258
 .B \-\-pkcs12 file
4250 4259
 Specify a PKCS #12 file containing local private key,
4251 4260
 local certificate, and root CA certificate.
... ...
@@ -577,6 +577,9 @@ static const char usage_message[] =
577 577
   "                  by a Certificate Authority in --ca file.\n"
578 578
   "--extra-certs file : one or more PEM certs that complete the cert chain.\n"
579 579
   "--key file      : Local private key in .pem format.\n"
580
+  "--tls-version-min <version> ['or-highest'] : sets the minimum TLS version we\n"
581
+  "    will accept from the peer.  If version is unrecognized and 'or-highest'\n"
582
+  "    is specified, require max TLS version supported by SSL implementation.\n"
580 583
 #ifndef ENABLE_CRYPTO_POLARSSL
581 584
   "--pkcs12 file   : PKCS#12 file containing local private key, local certificate\n"
582 585
   "                  and optionally the root CA certificate.\n"
... ...
@@ -6501,6 +6504,19 @@ add_option (struct options *options,
6501 6501
 	  options->priv_key_file_inline = p[2];
6502 6502
 	}
6503 6503
     }
6504
+  else if (streq (p[0], "tls-version-min") && p[1])
6505
+    {
6506
+      int ver;
6507
+      VERIFY_PERMISSION (OPT_P_GENERAL);
6508
+      ver = tls_version_min_parse(p[1], p[2]);
6509
+      if (ver == TLS_VER_BAD)
6510
+	{
6511
+	  msg (msglevel, "unknown tls-version-min parameter: %s", p[1]);
6512
+          goto err;
6513
+	}
6514
+      options->ssl_flags &= ~(SSLF_TLS_VERSION_MASK << SSLF_TLS_VERSION_SHIFT);
6515
+      options->ssl_flags |= (ver << SSLF_TLS_VERSION_SHIFT);
6516
+    }
6504 6517
 #ifndef ENABLE_CRYPTO_POLARSSL
6505 6518
   else if (streq (p[0], "pkcs12") && p[1])
6506 6519
     {
... ...
@@ -444,6 +444,27 @@ ssl_put_auth_challenge (const char *cr_str)
444 444
 #endif
445 445
 
446 446
 /*
447
+ * Parse a TLS version string, returning a TLS_VER_x constant.
448
+ * If version string is not recognized and extra == "or-highest",
449
+ * return tls_version_max().
450
+ */
451
+int
452
+tls_version_min_parse(const char *vstr, const char *extra)
453
+{
454
+  const int max_version = tls_version_max();
455
+  if (!strcmp(vstr, "1.0") && TLS_VER_1_0 <= max_version)
456
+    return TLS_VER_1_0;
457
+  else if (!strcmp(vstr, "1.1") && TLS_VER_1_1 <= max_version)
458
+    return TLS_VER_1_1;
459
+  else if (!strcmp(vstr, "1.2") && TLS_VER_1_2 <= max_version)
460
+    return TLS_VER_1_2;
461
+  else if (extra && !strcmp(extra, "or-highest"))
462
+    return max_version;
463
+  else
464
+    return TLS_VER_BAD;
465
+}
466
+
467
+/*
447 468
  * Initialize SSL context.
448 469
  * All files are in PEM format.
449 470
  */
... ...
@@ -101,6 +101,29 @@ void tls_free_lib();
101 101
 void tls_clear_error();
102 102
 
103 103
 /**
104
+ * Parse a TLS version specifier
105
+ *
106
+ * @param vstr		The TLS version string
107
+ * @param extra	        An optional extra parameter, may be NULL
108
+ *
109
+ * @return 		One of the TLS_VER_x constants or TLS_VER_BAD
110
+ *                      if a parse error should be flagged.
111
+ */
112
+#define TLS_VER_BAD   -1
113
+#define TLS_VER_1_0    0 /* default */
114
+#define TLS_VER_1_1    1
115
+#define TLS_VER_1_2    2
116
+int tls_version_min_parse(const char *vstr, const char *extra);
117
+
118
+/**
119
+ * Return the maximum TLS version (as a TLS_VER_x constant)
120
+ * supported by current SSL implementation
121
+ *
122
+ * @return 		One of the TLS_VER_x constants (but not TLS_VER_BAD).
123
+ */
124
+int tls_version_max(void);
125
+
126
+/**
104 127
  * Initialise a library-specific TLS context for a server.
105 128
  *
106 129
  * @param ctx		TLS context to initialise
... ...
@@ -290,12 +290,14 @@ struct tls_options
290 290
   struct compress_options comp_options;
291 291
 #endif
292 292
 
293
-  /* configuration file boolean options */
293
+  /* configuration file SSL-related boolean and low-permutation options */
294 294
 # define SSLF_CLIENT_CERT_NOT_REQUIRED (1<<0)
295 295
 # define SSLF_USERNAME_AS_COMMON_NAME  (1<<1)
296 296
 # define SSLF_AUTH_USER_PASS_OPTIONAL  (1<<2)
297 297
 # define SSLF_OPT_VERIFY               (1<<4)
298 298
 # define SSLF_CRL_VERIFY_DIR           (1<<5)
299
+# define SSLF_TLS_VERSION_SHIFT        6
300
+# define SSLF_TLS_VERSION_MASK         0xF /* (uses bit positions 6 to 9) */
299 301
   unsigned int ssl_flags;
300 302
 
301 303
 #ifdef MANAGEMENT_DEF_AUTH
... ...
@@ -114,7 +114,7 @@ tls_ctx_server_new(struct tls_root_ctx *ctx)
114 114
 {
115 115
   ASSERT(NULL != ctx);
116 116
 
117
-  ctx->ctx = SSL_CTX_new (TLSv1_server_method ());
117
+  ctx->ctx = SSL_CTX_new (SSLv23_server_method ());
118 118
 
119 119
   if (ctx->ctx == NULL)
120 120
     msg (M_SSLERR, "SSL_CTX_new TLSv1_server_method");
... ...
@@ -127,7 +127,7 @@ tls_ctx_client_new(struct tls_root_ctx *ctx)
127 127
 {
128 128
   ASSERT(NULL != ctx);
129 129
 
130
-  ctx->ctx = SSL_CTX_new (TLSv1_client_method ());
130
+  ctx->ctx = SSL_CTX_new (SSLv23_client_method ());
131 131
 
132 132
   if (ctx->ctx == NULL)
133 133
     msg (M_SSLERR, "SSL_CTX_new TLSv1_client_method");
... ...
@@ -174,13 +174,46 @@ info_callback (INFO_CALLBACK_SSL_CONST SSL * s, int where, int ret)
174 174
     }
175 175
 }
176 176
 
177
+/*
178
+ * Return maximum TLS version supported by local OpenSSL library.
179
+ * Assume that presence of SSL_OP_NO_TLSvX macro indicates that
180
+ * TLSvX is supported.
181
+ */
182
+int
183
+tls_version_max(void)
184
+{
185
+#if defined(SSL_OP_NO_TLSv1_2)
186
+  return TLS_VER_1_2;
187
+#elif defined(SSL_OP_NO_TLSv1_1)
188
+  return TLS_VER_1_1;
189
+#else
190
+  return TLS_VER_1_0;
191
+#endif
192
+}
193
+
177 194
 void
178 195
 tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags)
179 196
 {
180 197
   ASSERT(NULL != ctx);
181 198
 
199
+  /* process SSL options including minimum TLS version we will accept from peer */
200
+  {
201
+    long sslopt = SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
202
+    const int tls_version_min = (ssl_flags >> SSLF_TLS_VERSION_SHIFT) & SSLF_TLS_VERSION_MASK;
203
+    if (tls_version_min > TLS_VER_1_0)
204
+      sslopt |= SSL_OP_NO_TLSv1;
205
+#ifdef SSL_OP_NO_TLSv1_1
206
+    if (tls_version_min > TLS_VER_1_1)
207
+      sslopt |= SSL_OP_NO_TLSv1_1;
208
+#endif
209
+#ifdef SSL_OP_NO_TLSv1_2
210
+    if (tls_version_min > TLS_VER_1_2)
211
+      sslopt |= SSL_OP_NO_TLSv1_2;
212
+#endif
213
+    SSL_CTX_set_options (ctx->ctx, sslopt);
214
+  }
215
+
182 216
   SSL_CTX_set_session_cache_mode (ctx->ctx, SSL_SESS_CACHE_OFF);
183
-  SSL_CTX_set_options (ctx->ctx, SSL_OP_SINGLE_DH_USE);
184 217
   SSL_CTX_set_default_passwd_cb (ctx->ctx, pem_password_callback);
185 218
 
186 219
   /* Require peer certificate verification */
... ...
@@ -501,6 +501,18 @@ void tls_ctx_personalise_random(struct tls_root_ctx *ctx)
501 501
     }
502 502
 }
503 503
 
504
+int
505
+tls_version_max(void)
506
+{
507
+#if defined(SSL_MAJOR_VERSION_3) && defined(SSL_MINOR_VERSION_3)
508
+  return TLS_VER_1_2;
509
+#elif defined(SSL_MAJOR_VERSION_3) && defined(SSL_MINOR_VERSION_2)
510
+  return TLS_VER_1_1;
511
+#else
512
+  return TLS_VER_1_0;
513
+#endif
514
+}
515
+
504 516
 void key_state_ssl_init(struct key_state_ssl *ks_ssl,
505 517
     const struct tls_root_ctx *ssl_ctx, bool is_server, struct tls_session *session)
506 518
 {
... ...
@@ -550,6 +562,34 @@ void key_state_ssl_init(struct key_state_ssl *ks_ssl,
550 550
       /* TODO: PolarSSL does not currently support sending the CA chain to the client */
551 551
       ssl_set_ca_chain (ks_ssl->ctx, ssl_ctx->ca_chain, NULL, NULL );
552 552
 
553
+      /* Initialize minimum TLS version */
554
+      {
555
+	const int tls_version_min = (session->opt->ssl_flags >> SSLF_TLS_VERSION_SHIFT) & SSLF_TLS_VERSION_MASK;
556
+	int polar_major;
557
+	int polar_minor;
558
+	switch (tls_version_min)
559
+	  {
560
+	  case TLS_VER_1_0:
561
+	  default:
562
+	    polar_major = SSL_MAJOR_VERSION_3;
563
+	    polar_minor = SSL_MINOR_VERSION_1;
564
+	    break;
565
+#if defined(SSL_MAJOR_VERSION_3) && defined(SSL_MINOR_VERSION_2)
566
+	  case TLS_VER_1_1:
567
+	    polar_major = SSL_MAJOR_VERSION_3;
568
+	    polar_minor = SSL_MINOR_VERSION_2;
569
+	    break;
570
+#endif
571
+#if defined(SSL_MAJOR_VERSION_3) && defined(SSL_MINOR_VERSION_3)
572
+	  case TLS_VER_1_2:
573
+	    polar_major = SSL_MAJOR_VERSION_3;
574
+	    polar_minor = SSL_MINOR_VERSION_3;
575
+	    break;
576
+#endif
577
+	  }
578
+	ssl_set_min_version(ks_ssl->ctx, polar_major, polar_minor);
579
+      }
580
+
553 581
       /* Initialise BIOs */
554 582
       ALLOC_OBJ_CLEAR (ks_ssl->ct_in, endless_buffer);
555 583
       ALLOC_OBJ_CLEAR (ks_ssl->ct_out, endless_buffer);