Bläddra i källkod

tls: options to set TLS versions lower limit

- example: if method is set to TLSv1.1+, then the connection must be
  TLSv1.1 or newer
- closes FS#502
Daniel-Constantin Mierla 10 år sedan
förälder
incheckning
711833b82d
4 ändrade filer med 64 tillägg och 17 borttagningar
  1. 9 4
      modules/tls/tls_config.c
  2. 13 1
      modules/tls/tls_domain.c
  3. 25 8
      modules/tls/tls_domain.h
  4. 17 4
      modules/tls/tls_init.c

+ 9 - 4
modules/tls/tls_config.c

@@ -114,8 +114,13 @@ static cfg_option_t methods[] = {
 	{"SSLv3",   .val = TLS_USE_SSLv3},
 	{"SSLv23",  .val = TLS_USE_SSLv23},
 	{"TLSv1",   .val = TLS_USE_TLSv1},
-	{"TLSv1.1", .val = TLS_USE_TLSv1_1},
-	{"TLSv1.2", .val = TLS_USE_TLSv1_2},
+	{"TLSv1.0", .val = TLS_USE_TLSv1},
+	{"TLSv1+",  .val = TLS_USE_TLSv1_PLUS},
+	{"TLSv1.0+", .val = TLS_USE_TLSv1_PLUS},
+	{"TLSv1.1",  .val = TLS_USE_TLSv1_1},
+	{"TLSv1.1+", .val = TLS_USE_TLSv1_1_PLUS},
+	{"TLSv1.2",  .val = TLS_USE_TLSv1_2},
+	{"TLSv1.2+", .val = TLS_USE_TLSv1_2_PLUS},
 	{0}
 };
 
@@ -455,14 +460,14 @@ int tls_parse_method(str* method)
 	if (!opt) return -1;
 
 #if OPENSSL_VERSION_NUMBER < 0x1000100fL
-	if(opt->val == TLS_USE_TLSv1_1) {
+	if(opt->val == TLS_USE_TLSv1_1 || opt->val == TLS_USE_TLSv1_1_PLUS) {
 		LM_ERR("tls v1.1 not supported by this libssl version: %ld\n",
 				(long)OPENSSL_VERSION_NUMBER);
 		return -1;
 	}
 #endif
 #if OPENSSL_VERSION_NUMBER < 0x1000105fL
-	if(opt->val == TLS_USE_TLSv1_2) {
+	if(opt->val == TLS_USE_TLSv1_2 || opt->val == TLS_USE_TLSv1_2_PLUS) {
 		LM_ERR("tls v1.2 not supported by this libssl version: %ld\n",
 				(long)OPENSSL_VERSION_NUMBER);
 		return -1;

+ 13 - 1
modules/tls/tls_domain.c

@@ -896,13 +896,25 @@ static int fix_domain(tls_domain_t* d, tls_domain_t* def)
 		ERR("%s: Cannot allocate shared memory\n", tls_domain_str(d));
 		return -1;
 	}
+	if(d->method>TLS_USE_TLSvRANGE) {
+		LM_DBG("using tls methods range: %d\n", d->method);
+	} else {
+		LM_DBG("using one tls method version: %d\n", d->method);
+	}
 	memset(d->ctx, 0, sizeof(SSL_CTX*) * procs_no);
 	for(i = 0; i < procs_no; i++) {
-		d->ctx[i] = SSL_CTX_new((SSL_METHOD*)ssl_methods[d->method - 1]);
+		if(d->method>TLS_USE_TLSvRANGE) {
+			d->ctx[i] = SSL_CTX_new(SSLv23_method());
+		} else {
+			d->ctx[i] = SSL_CTX_new((SSL_METHOD*)ssl_methods[d->method - 1]);
+		}
 		if (d->ctx[i] == NULL) {
 			ERR("%s: Cannot create SSL context\n", tls_domain_str(d));
 			return -1;
 		}
+		if(d->method>TLS_USE_TLSvRANGE) {
+			SSL_CTX_set_options(d->ctx[i], (long)ssl_methods[d->method - 1]);
+		}
 	}
 	
 	if (load_cert(d) < 0) return -1;

+ 25 - 8
modules/tls/tls_domain.h

@@ -33,29 +33,46 @@
 #include <openssl/ssl.h>
 
 
+#define TLS_OP_SSLv2_PLUS   0
+#define TLS_OP_SSLv3_PLUS   (TLS_OP_SSLv2_PLUS   | SSL_OP_NO_SSLv2)
+#define TLS_OP_TLSv1_PLUS   (TLS_OP_SSLv3_PLUS   | SSL_OP_NO_SSLv3)
+
+#ifdef SSL_OP_NO_TLSv1
+#  define TLS_OP_TLSv1_1_PLUS (TLS_OP_TLSv1_PLUS   | SSL_OP_NO_TLSv1)
+
+#  ifdef SSL_OP_NO_TLSv1_1
+#    define TLS_OP_TLSv1_2_PLUS (TLS_OP_TLSv1_1_PLUS | SSL_OP_NO_TLSv1_1)
+#  endif /*SSL_OP_NO_TLSv1_1*/
+
+#endif /*SSL_OP_NO_TLSv1*/
+
 /**
  * Available TLS methods
  */
 enum tls_method {
 	TLS_METHOD_UNSPEC = 0,
+	TLS_USE_SSLv23_cli,
+	TLS_USE_SSLv23_srv,
+	TLS_USE_SSLv23,     /* any SSL/TLS version */
 	TLS_USE_SSLv2_cli,
 	TLS_USE_SSLv2_srv,
-	TLS_USE_SSLv2,
+	TLS_USE_SSLv2,      /* only SSLv2 (deprecated) */
 	TLS_USE_SSLv3_cli,
 	TLS_USE_SSLv3_srv,
-	TLS_USE_SSLv3,
+	TLS_USE_SSLv3,      /* only SSLv3 (insecure) */
 	TLS_USE_TLSv1_cli,
 	TLS_USE_TLSv1_srv,
-	TLS_USE_TLSv1,
-	TLS_USE_SSLv23_cli,
-	TLS_USE_SSLv23_srv,
-	TLS_USE_SSLv23,
+	TLS_USE_TLSv1,      /* only TLSv1.0 */
 	TLS_USE_TLSv1_1_cli,
 	TLS_USE_TLSv1_1_srv,
-	TLS_USE_TLSv1_1,
+	TLS_USE_TLSv1_1,    /* only TLSv1.1 */
 	TLS_USE_TLSv1_2_cli,
 	TLS_USE_TLSv1_2_srv,
-	TLS_USE_TLSv1_2,
+	TLS_USE_TLSv1_2,    /* only TLSv1.2 */
+	TLS_USE_TLSvRANGE,    /* placeholder - TLSvX ranges must be after it */
+	TLS_USE_TLSv1_PLUS,   /* TLSv1.0 or greater */
+	TLS_USE_TLSv1_1_PLUS, /* TLSv1.1 or greater */
+	TLS_USE_TLSv1_2_PLUS, /* TLSv1.1 or greater */
 	TLS_METHOD_MAX
 };
 

+ 17 - 4
modules/tls/tls_init.c

@@ -329,6 +329,12 @@ static void init_ssl_methods(void)
 {
 	memset(ssl_methods, 0, sizeof(ssl_methods));
 
+	/* any SSL/TLS version */
+	ssl_methods[TLS_USE_SSLv23_cli - 1] = SSLv23_client_method();
+	ssl_methods[TLS_USE_SSLv23_srv - 1] = SSLv23_server_method();
+	ssl_methods[TLS_USE_SSLv23 - 1] = SSLv23_method();
+
+	/* only specific SSL or TLS version */
 #ifndef OPENSSL_NO_SSL2
 	ssl_methods[TLS_USE_SSLv2_cli - 1] = SSLv2_client_method();
 	ssl_methods[TLS_USE_SSLv2_srv - 1] = SSLv2_server_method();
@@ -343,10 +349,6 @@ static void init_ssl_methods(void)
 	ssl_methods[TLS_USE_TLSv1_srv - 1] = TLSv1_server_method();
 	ssl_methods[TLS_USE_TLSv1 - 1] = TLSv1_method();
 
-	ssl_methods[TLS_USE_SSLv23_cli - 1] = SSLv23_client_method();
-	ssl_methods[TLS_USE_SSLv23_srv - 1] = SSLv23_server_method();
-	ssl_methods[TLS_USE_SSLv23 - 1] = SSLv23_method();
-
 #if OPENSSL_VERSION_NUMBER >= 0x1000100fL
 	ssl_methods[TLS_USE_TLSv1_1_cli - 1] = TLSv1_1_client_method();
 	ssl_methods[TLS_USE_TLSv1_1_srv - 1] = TLSv1_1_server_method();
@@ -358,6 +360,17 @@ static void init_ssl_methods(void)
 	ssl_methods[TLS_USE_TLSv1_2_srv - 1] = TLSv1_2_server_method();
 	ssl_methods[TLS_USE_TLSv1_2 - 1] = TLSv1_2_method();
 #endif
+
+	/* ranges of TLS versions (require a minimum TLS version) */
+	ssl_methods[TLS_USE_TLSv1_PLUS - 1] = (void*)TLS_OP_TLSv1_PLUS;
+
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL
+	ssl_methods[TLS_USE_TLSv1_1_PLUS - 1] = (void*)TLS_OP_TLSv1_1_PLUS;
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x1000105fL
+	ssl_methods[TLS_USE_TLSv1_2_PLUS - 1] = (void*)TLS_OP_TLSv1_2_PLUS;
+#endif
 }