Browse code

Fix --tls-version-min and --tls-version-max for OpenSSL 1.1+

As described in <80e6b449-c536-dc87-7215-3693872bce5a@birkenwald.de> on
the openvpn-devel mailing list, --tls-version-min no longer works with
OpenSSL 1.1. Kurt Roeckx posted in a debian bug report:

"This is marked as important because if you switch to openssl 1.1.0
the defaults minimum version in Debian is currently TLS 1.2 and
you can't override it with the options that you're currently using
(and are deprecated)."

This patch is loosely based on the original patch by Kurt, but solves the
issue by adding functions to openssl-compat.h, like we also did for all
other openssl 1.1. breakage. This results in not having to add more ifdefs
in ssl_openssl.c and thus cleaner code.

Signed-off-by: Steffan Karger <steffan@karger.me>
Acked-by: Selva Nair <selva.nair@gmail.com>
Message-Id: <20180119212721.25177-1-steffan@karger.me>
URL: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=873302
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg16284.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Steffan Karger authored on 2018/01/20 06:27:21
Showing 5 changed files
... ...
@@ -661,4 +661,71 @@ EC_GROUP_order_bits(const EC_GROUP *group)
661 661
 #define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT       RSA_F_RSA_EAY_PRIVATE_ENCRYPT
662 662
 #endif
663 663
 
664
+#ifndef SSL_CTX_get_min_proto_version
665
+/** Dummy SSL_CTX_get_min_proto_version for OpenSSL < 1.1 (not really needed) */
666
+static inline int
667
+SSL_CTX_get_min_proto_version(SSL_CTX *ctx)
668
+{
669
+    return 0;
670
+}
671
+#endif /* SSL_CTX_get_min_proto_version */
672
+
673
+#ifndef SSL_CTX_set_min_proto_version
674
+/** Mimics SSL_CTX_set_min_proto_version for OpenSSL < 1.1 */
675
+static inline int
676
+SSL_CTX_set_min_proto_version(SSL_CTX *ctx, long tls_ver_min)
677
+{
678
+    long sslopt = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; /* Never do < TLS 1.0 */
679
+
680
+    if (tls_ver_min > TLS1_VERSION)
681
+    {
682
+        sslopt |= SSL_OP_NO_TLSv1;
683
+    }
684
+#ifdef SSL_OP_NO_TLSv1_1
685
+    if (tls_ver_min > TLS1_1_VERSION)
686
+    {
687
+        sslopt |= SSL_OP_NO_TLSv1_1;
688
+    }
689
+#endif
690
+#ifdef SSL_OP_NO_TLSv1_2
691
+    if (tls_ver_min > TLS1_2_VERSION)
692
+    {
693
+        sslopt |= SSL_OP_NO_TLSv1_2;
694
+    }
695
+#endif
696
+    SSL_CTX_set_options(ctx, sslopt);
697
+
698
+    return 1;
699
+}
700
+#endif /* SSL_CTX_set_min_proto_version */
701
+
702
+#ifndef SSL_CTX_set_max_proto_version
703
+/** Mimics SSL_CTX_set_max_proto_version for OpenSSL < 1.1 */
704
+static inline int
705
+SSL_CTX_set_max_proto_version(SSL_CTX *ctx, long tls_ver_max)
706
+{
707
+    long sslopt = 0;
708
+
709
+    if (tls_ver_max < TLS1_VERSION)
710
+    {
711
+        sslopt |= SSL_OP_NO_TLSv1;
712
+    }
713
+#ifdef SSL_OP_NO_TLSv1_1
714
+    if (tls_ver_max < TLS1_1_VERSION)
715
+    {
716
+        sslopt |= SSL_OP_NO_TLSv1_1;
717
+    }
718
+#endif
719
+#ifdef SSL_OP_NO_TLSv1_2
720
+    if (tls_ver_max < TLS1_2_VERSION)
721
+    {
722
+        sslopt |= SSL_OP_NO_TLSv1_2;
723
+    }
724
+#endif
725
+    SSL_CTX_set_options(ctx, sslopt);
726
+
727
+    return 1;
728
+}
729
+#endif /* SSL_CTX_set_max_proto_version */
730
+
664 731
 #endif /* OPENSSL_COMPAT_H_ */
... ...
@@ -622,7 +622,10 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)
622 622
      * cipher restrictions before loading certificates */
623 623
     tls_ctx_restrict_ciphers(new_ctx, options->cipher_list);
624 624
 
625
-    tls_ctx_set_options(new_ctx, options->ssl_flags);
625
+    if (!tls_ctx_set_options(new_ctx, options->ssl_flags))
626
+    {
627
+        goto err;
628
+    }
626 629
 
627 630
     if (options->pkcs12_file)
628 631
     {
... ...
@@ -162,8 +162,10 @@ bool tls_ctx_initialised(struct tls_root_ctx *ctx);
162 162
  *
163 163
  * @param ctx           TLS context to set options on
164 164
  * @param ssl_flags     SSL flags to set
165
+ *
166
+ * @return true on success, false otherwise.
165 167
  */
166
-void tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags);
168
+bool tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags);
167 169
 
168 170
 /**
169 171
  * Restrict the list of ciphers that can be used within the TLS context.
... ...
@@ -206,9 +206,10 @@ key_state_export_keying_material(struct key_state_ssl *ssl,
206 206
 {
207 207
 }
208 208
 
209
-void
209
+bool
210 210
 tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags)
211 211
 {
212
+    return true;
212 213
 }
213 214
 
214 215
 static const char *
... ...
@@ -206,16 +206,65 @@ info_callback(INFO_CALLBACK_SSL_CONST SSL *s, int where, int ret)
206 206
 int
207 207
 tls_version_max(void)
208 208
 {
209
-#if defined(SSL_OP_NO_TLSv1_2)
209
+#if defined(TLS1_2_VERSION) || defined(SSL_OP_NO_TLSv1_2)
210 210
     return TLS_VER_1_2;
211
-#elif defined(SSL_OP_NO_TLSv1_1)
211
+#elif defined(TLS1_1_VERSION) || defined(SSL_OP_NO_TLSv1_1)
212 212
     return TLS_VER_1_1;
213 213
 #else
214 214
     return TLS_VER_1_0;
215 215
 #endif
216 216
 }
217 217
 
218
-void
218
+/** Convert internal version number to openssl version number */
219
+static int
220
+openssl_tls_version(int ver)
221
+{
222
+    if (ver == TLS_VER_1_0)
223
+    {
224
+        return TLS1_VERSION;
225
+    }
226
+    else if (ver == TLS_VER_1_1)
227
+    {
228
+        return TLS1_1_VERSION;
229
+    }
230
+    else if (ver == TLS_VER_1_2)
231
+    {
232
+        return TLS1_2_VERSION;
233
+    }
234
+    return 0;
235
+}
236
+
237
+static bool
238
+tls_ctx_set_tls_versions(struct tls_root_ctx *ctx, unsigned int ssl_flags)
239
+{
240
+    int tls_ver_min = openssl_tls_version(
241
+        (ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT) & SSLF_TLS_VERSION_MIN_MASK);
242
+    int tls_ver_max = openssl_tls_version(
243
+        (ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) & SSLF_TLS_VERSION_MAX_MASK);
244
+
245
+    if (!tls_ver_min)
246
+    {
247
+        /* Enforce at least TLS 1.0 */
248
+        int cur_min = SSL_CTX_get_min_proto_version(ctx->ctx);
249
+        tls_ver_min = cur_min < TLS1_VERSION ? TLS1_VERSION : cur_min;
250
+    }
251
+
252
+    if (!SSL_CTX_set_min_proto_version(ctx->ctx, tls_ver_min))
253
+    {
254
+        msg(D_TLS_ERRORS, "%s: failed to set minimum TLS version", __func__);
255
+        return false;
256
+    }
257
+
258
+    if (tls_ver_max && !SSL_CTX_set_max_proto_version(ctx->ctx, tls_ver_max))
259
+    {
260
+        msg(D_TLS_ERRORS, "%s: failed to set maximum TLS version", __func__);
261
+        return false;
262
+    }
263
+
264
+    return true;
265
+}
266
+
267
+bool
219 268
 tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags)
220 269
 {
221 270
     ASSERT(NULL != ctx);
... ...
@@ -223,41 +272,18 @@ tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags)
223 223
     /* default certificate verification flags */
224 224
     int flags = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
225 225
 
226
-    /* process SSL options including minimum TLS version we will accept from peer */
227
-    {
228
-        long sslopt = SSL_OP_SINGLE_DH_USE | SSL_OP_NO_TICKET | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
229
-        int tls_ver_max = TLS_VER_UNSPEC;
230
-        const int tls_ver_min =
231
-            (ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT) & SSLF_TLS_VERSION_MIN_MASK;
232
-
233
-        tls_ver_max =
234
-            (ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) & SSLF_TLS_VERSION_MAX_MASK;
235
-        if (tls_ver_max <= TLS_VER_UNSPEC)
236
-        {
237
-            tls_ver_max = tls_version_max();
238
-        }
239
-
240
-        if (tls_ver_min > TLS_VER_1_0 || tls_ver_max < TLS_VER_1_0)
241
-        {
242
-            sslopt |= SSL_OP_NO_TLSv1;
243
-        }
244
-#ifdef SSL_OP_NO_TLSv1_1
245
-        if (tls_ver_min > TLS_VER_1_1 || tls_ver_max < TLS_VER_1_1)
246
-        {
247
-            sslopt |= SSL_OP_NO_TLSv1_1;
248
-        }
249
-#endif
250
-#ifdef SSL_OP_NO_TLSv1_2
251
-        if (tls_ver_min > TLS_VER_1_2 || tls_ver_max < TLS_VER_1_2)
252
-        {
253
-            sslopt |= SSL_OP_NO_TLSv1_2;
254
-        }
255
-#endif
226
+    /* process SSL options */
227
+    long sslopt = SSL_OP_SINGLE_DH_USE | SSL_OP_NO_TICKET;
256 228
 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
257
-        sslopt |= SSL_OP_CIPHER_SERVER_PREFERENCE;
229
+    sslopt |= SSL_OP_CIPHER_SERVER_PREFERENCE;
258 230
 #endif
259
-        sslopt |= SSL_OP_NO_COMPRESSION;
260
-        SSL_CTX_set_options(ctx->ctx, sslopt);
231
+    sslopt |= SSL_OP_NO_COMPRESSION;
232
+
233
+    SSL_CTX_set_options(ctx->ctx, sslopt);
234
+
235
+    if (!tls_ctx_set_tls_versions(ctx, ssl_flags))
236
+    {
237
+        return false;
261 238
     }
262 239
 
263 240
 #ifdef SSL_MODE_RELEASE_BUFFERS
... ...
@@ -280,6 +306,8 @@ tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags)
280 280
     SSL_CTX_set_verify(ctx->ctx, flags, verify_callback);
281 281
 
282 282
     SSL_CTX_set_info_callback(ctx->ctx, info_callback);
283
+
284
+    return true;
283 285
 }
284 286
 
285 287
 void