git: 81b2ab51138d - stable/13 - rpc.tlsservd: Add an option to allow TLS version 1.2

From: Rick Macklem <rmacklem_at_FreeBSD.org>
Date: Fri, 03 Jun 2022 02:15:16 UTC
The branch stable/13 has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=81b2ab51138d5a994bbdd49c2c21ff8812ed9d3c

commit 81b2ab51138d5a994bbdd49c2c21ff8812ed9d3c
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2022-05-20 21:44:50 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2022-06-03 02:14:13 +0000

    rpc.tlsservd: Add an option to allow TLS version 1.2
    
    Commit 0b4f2ab0e913 fixes the krpc so that it can use TLS
    version 1.3 for NFS-over-TLS, as required by
    the draft (someday to be an RFC).
    Since FreeBSD 13.0, 13.1 use TLS version 1.2 for
    NFS-over-TLS mounts, this command line option
    may be used so that mounts from 13.0, 13.1 will still work.
    
    Without the command line option, only TLS version 1.3
    mounts are permitted.
    
    The man page update will be a separate commit.
    
    (cherry picked from commit 0637b12b13be442aacda808bb937d45e538dd98f)
---
 usr.sbin/rpc.tlsservd/rpc.tlsservd.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/usr.sbin/rpc.tlsservd/rpc.tlsservd.c b/usr.sbin/rpc.tlsservd/rpc.tlsservd.c
index 9ae3355805a1..96f3c06a5c2e 100644
--- a/usr.sbin/rpc.tlsservd/rpc.tlsservd.c
+++ b/usr.sbin/rpc.tlsservd/rpc.tlsservd.c
@@ -105,6 +105,7 @@ static bool		rpctls_cnuser = false;
 static char		*rpctls_dnsname;
 static const char	*rpctls_cnuseroid = "1.3.6.1.4.1.2238.1.1.1";
 static const char	*rpctls_ciphers = NULL;
+static int		rpctls_mintls = TLS1_3_VERSION;
 
 static void		rpctlssd_terminate(int);
 static SSL_CTX		*rpctls_setup_ssl(const char *certdir);
@@ -119,6 +120,7 @@ static void		rpctls_huphandler(int sig __unused);
 extern void		rpctlssd_1(struct svc_req *rqstp, SVCXPRT *transp);
 
 static struct option longopts[] = {
+	{ "allowtls1_2",	no_argument,		NULL,	'2' },
 	{ "ciphers",		required_argument,	NULL,	'C' },
 	{ "certdir",		required_argument,	NULL,	'D' },
 	{ "debuglevel",		no_argument,		NULL,	'd' },
@@ -181,9 +183,12 @@ main(int argc, char **argv)
 
 	debug = 0;
 	rpctls_verbose = false;
-	while ((ch = getopt_long(argc, argv, "C:D:dhl:n:mp:r:uvWw", longopts,
+	while ((ch = getopt_long(argc, argv, "2C:D:dhl:n:mp:r:uvWw", longopts,
 	    NULL)) != -1) {
 		switch (ch) {
+		case '2':
+			rpctls_mintls = TLS1_2_VERSION;
+			break;
 		case 'C':
 			rpctls_ciphers = optarg;
 			break;
@@ -580,6 +585,21 @@ rpctls_setup_ssl(const char *certdir)
 		}
 	}
 
+	ret = SSL_CTX_set_min_proto_version(ctx, rpctls_mintls);
+	if (ret == 0) {
+		rpctls_verbose_out("rpctls_setup_ssl: "
+		    "SSL_CTX_set_min_proto_version failed\n");
+		SSL_CTX_free(ctx);
+		return (NULL);
+	}
+	ret = SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
+	if (ret == 0) {
+		rpctls_verbose_out("rpctls_setup_ssl: "
+		    "SSL_CTX_set_max_proto_version failed\n");
+		SSL_CTX_free(ctx);
+		return (NULL);
+	}
+
 	/* Get the cert.pem and certkey.pem files from the directory certdir. */
 	len = strlcpy(path, certdir, sizeof(path));
 	rlen = sizeof(path) - len;