NetBSD Problem Report #55830

From www@netbsd.org  Sat Nov 28 06:40:07 2020
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id D64AC1A921F
	for <gnats-bugs@gnats.NetBSD.org>; Sat, 28 Nov 2020 06:40:07 +0000 (UTC)
Message-Id: <20201128064006.979E41A923F@mollari.NetBSD.org>
Date: Sat, 28 Nov 2020 06:40:06 +0000 (UTC)
From: sunil@nimmagadda.net
Reply-To: sunil@nimmagadda.net
To: gnats-bugs@NetBSD.org
Subject: bozohttpd(8): Make SSL protocol version selection a runtime option.
X-Send-Pr-Version: www-1.0

>Number:         55830
>Category:       bin
>Synopsis:       bozohttpd(8): Make SSL protocol version selection a runtime option.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Nov 28 06:45:00 +0000 2020
>Originator:     Sunil Nimmagadda
>Release:        netbsd-current
>Organization:
>Environment:
NetBSD x230.nimmagadda.net 9.99.75 NetBSD 9.99.75 (GENERIC) #0: Mon Nov 16 19:02:54 IST 2020  skn@x230.nimmagadda.net:/home/skn/obj/home/skn/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
The attached diff enables to set TLS version at runtime. Prior discussion thread on current-users here http://mail-index.netbsd.org/current-users/2020/10/22/msg039734.html

Raising a PR on mrg@'s request. 
>How-To-Repeat:

>Fix:
diff --git a/libexec/httpd/bozohttpd.8 b/libexec/httpd/bozohttpd.8
--- a/libexec/httpd/bozohttpd.8
+++ b/libexec/httpd/bozohttpd.8
@@ -39,6 +39,7 @@
 .Op Fl I Ar port
 .Op Fl L Ar prefix script
 .Op Fl M Ar suffix type encoding encoding11
+.Op Fl m Ar version
 .Op Fl P Ar pidfile
 .Op Fl R Ar readme
 .Op Fl S Ar version
@@ -221,6 +222,18 @@
 Multiple
 .Fl M
 options may be passed.
+.It Fl m Ar version
+Set the minimum supported SSL protocol
+.Ar version .
+The valid values of
+.Ar version
+are
+.Dq TLSv1.1 ,
+.Dq TLSv1.2 ,
+and
+.Dq TLSv1.3 .
+The default version is
+.Dq TLSv1.1 .
 .It Fl n
 Stops
 .Nm
diff --git a/libexec/httpd/bozohttpd.h b/libexec/httpd/bozohttpd.h
--- a/libexec/httpd/bozohttpd.h
+++ b/libexec/httpd/bozohttpd.h
@@ -313,6 +313,7 @@
 #ifdef NO_SSL_SUPPORT
 #define bozo_ssl_set_opts(w, x, y)			bozo_noop
 #define bozo_ssl_set_ciphers(w, x)			bozo_noop
+#define bozo_ssl_set_min_proto(x)			bozo_noop
 #define bozo_ssl_init(x)				bozo_noop
 #define bozo_ssl_accept(x)				(0)
 #define bozo_ssl_shutdown(x)				bozo_noop
@@ -321,6 +322,7 @@
 #else
 void	bozo_ssl_set_opts(bozohttpd_t *, const char *, const char *);
 void	bozo_ssl_set_ciphers(bozohttpd_t *, const char *);
+void	bozo_ssl_set_min_proto(bozohttpd_t *, const char *);
 void	bozo_ssl_init(bozohttpd_t *);
 int	bozo_ssl_accept(bozohttpd_t *);
 void	bozo_ssl_shutdown(bozohttpd_t *);
diff --git a/libexec/httpd/main.c b/libexec/httpd/main.c
--- a/libexec/httpd/main.c
+++ b/libexec/httpd/main.c
@@ -165,7 +165,7 @@
 	 */

 	while ((c = getopt(argc, argv,
-	    "C:EGHI:L:M:P:R:S:T:U:VXZ:bc:defhi:np:st:uv:x:z:")) != -1) {
+	    "C:EGHI:L:M:m:P:R:S:T:U:VXZ:bc:defhi:np:st:uv:x:z:")) != -1) {
 		switch (c) {

 		case 'b':
@@ -283,6 +283,13 @@
 			optind += 3;
 			break;

+		case 'm':
+			if (!have_ssl)
+				goto no_ssl;
+
+			bozo_ssl_set_min_proto(&httpd, optarg);
+			break;
+
 		case 'n':
 			bozo_set_pref(&httpd, &prefs, "numeric", "true");
 			break;
diff --git a/libexec/httpd/ssl-bozo.c b/libexec/httpd/ssl-bozo.c
--- a/libexec/httpd/ssl-bozo.c
+++ b/libexec/httpd/ssl-bozo.c
@@ -61,13 +61,6 @@
 	"!KRB5-DES-CBC3-SHA"
 #endif

-#ifndef BOZO_SSL_OPTIONS
-#define BOZO_SSL_OPTIONS					\
-	((long)(SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1))
-#endif
-
-  /* this structure encapsulates the ssl info */
-
 /* this structure encapsulates the ssl info */
 typedef struct sslinfo_t {
 	SSL_CTX			*ssl_context;
@@ -76,6 +69,7 @@
 	char			*certificate_file;
 	char			*privatekey_file;
 	char			*ciphers;
+	char			*min_proto_version;
 } sslinfo_t;

 /*
@@ -204,11 +198,26 @@
 	return (ssize_t)ret;
 }

+static int
+bozo_ssl_version(const char *version)
+{
+
+	if (strcmp(version, "TLSv1.1") == 0)
+		return TLS1_1_VERSION;
+
+	if (strcmp(version, "TLSv1.2") == 0)
+		return TLS1_2_VERSION;
+
+	if (strcmp(version, "TLSv1.3") == 0)
+		return TLS1_3_VERSION;
+
+	return -1;
+}
 void
 bozo_ssl_init(bozohttpd_t *httpd)
 {
 	sslinfo_t *sslinfo = httpd->sslinfo;
-	long options;
+	int proto;

 	if (sslinfo == NULL || !sslinfo->certificate_file)
 		return;
@@ -222,12 +231,13 @@
 		bozo_ssl_err(httpd, EXIT_FAILURE,
 		    "SSL context creation failed");

-	options = SSL_CTX_set_options(sslinfo->ssl_context,
-	    BOZO_SSL_OPTIONS);
-	if ((options & BOZO_SSL_OPTIONS) != BOZO_SSL_OPTIONS)
+	proto = sslinfo->min_proto_version ?
+	    bozo_ssl_version(sslinfo->min_proto_version) : TLS1_1_VERSION;
+
+	if (!SSL_CTX_set_min_proto_version(sslinfo->ssl_context, proto))
 		bozo_ssl_err(httpd, EXIT_FAILURE,
-		    "Error setting ssl options requested %#lx, got %#lx",
-		    BOZO_SSL_OPTIONS, options);
+		    "Error setting minimum protocol version '%s'",
+		    sslinfo->min_proto_version);

 	if (!SSL_CTX_set_cipher_list(sslinfo->ssl_context,
 	    sslinfo->ciphers ? sslinfo->ciphers : BOZO_SSL_CIPHERS))
@@ -340,6 +350,15 @@
 	debug((httpd, DEBUG_NORMAL, "using ciphers: %s", sslinfo->ciphers));
 }

+void
+bozo_ssl_set_min_proto(bozohttpd_t *httpd, const char *version)
+{
+	sslinfo_t *sslinfo = bozo_get_sslinfo(httpd);
+
+	sslinfo->min_proto_version = bozostrdup(httpd, NULL, version);
+	debug((httpd, DEBUG_NORMAL,
+		"using minimum protocol version: %s", version));
+}
 #endif /* NO_SSL_SUPPORT */

 /*

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.