Add DTLSv1.2 support to openssl(1) s_client/s_server.
authorjsing <jsing@openbsd.org>
Wed, 17 Mar 2021 18:08:32 +0000 (18:08 +0000)
committerjsing <jsing@openbsd.org>
Wed, 17 Mar 2021 18:08:32 +0000 (18:08 +0000)
ok inoguchi@ tb@

usr.bin/openssl/apps.c
usr.bin/openssl/openssl.1
usr.bin/openssl/s_client.c
usr.bin/openssl/s_server.c

index 2c228aa..24a28c7 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: apps.c,v 1.57 2020/10/26 11:48:39 tb Exp $ */
+/* $OpenBSD: apps.c,v 1.58 2021/03/17 18:08:32 jsing Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
 #include <openssl/err.h>
 #include <openssl/pem.h>
 #include <openssl/pkcs12.h>
+#include <openssl/rsa.h>
 #include <openssl/safestack.h>
+#include <openssl/ssl.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
-#include <openssl/rsa.h>
-
 typedef struct {
        const char *name;
        unsigned long flag;
@@ -2337,3 +2337,9 @@ show_cipher(const OBJ_NAME *name, void *arg)
        fprintf(stderr, " -%-24s%s", name->name, (++*n % 3 != 0 ? "" : "\n"));
 }
 
+int
+SSL_is_dtls(const SSL *s)
+{
+       return SSL_version(s) == DTLS1_VERSION ||
+           SSL_version(s) == DTLS1_2_VERSION;
+}
index 9cd977c..84627a8 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: openssl.1,v 1.128 2020/12/30 08:26:44 tb Exp $
+.\" $OpenBSD: openssl.1,v 1.129 2021/03/17 18:08:32 jsing Exp $
 .\" ====================================================================
 .\" Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
 .\"
 .\" copied and put under another distribution licence
 .\" [including the GNU Public Licence.]
 .\"
-.Dd $Mdocdate: December 30 2020 $
+.Dd $Mdocdate: March 17 2021 $
 .Dt OPENSSL 1
 .Os
 .Sh NAME
@@ -4280,7 +4280,9 @@ Verify the input data and output the recovered data.
 .Op Fl crl_check_all
 .Op Fl crlf
 .Op Fl debug
+.Op Fl dtls
 .Op Fl dtls1
+.Op Fl dtls1_2
 .Op Fl extended_crl
 .Op Fl groups Ar list
 .Op Fl host Ar host
@@ -4424,8 +4426,12 @@ Translate a line feed from the terminal into CR+LF,
 as required by some servers.
 .It Fl debug
 Print extensive debugging information, including a hex dump of all traffic.
+.It Fl dtls
+Permit any version of DTLS.
 .It Fl dtls1
 Permit only DTLS1.0.
+.It Fl dtls1_2
+Permit only DTLS1.2.
 .It Fl groups Ar list
 Set the supported elliptic curve groups to the colon separated
 .Ar list
@@ -4588,7 +4594,9 @@ will be used.
 .Op Fl dkey Ar file
 .Op Fl dkeyform Cm der | pem
 .Op Fl dpass Ar arg
+.Op Fl dtls
 .Op Fl dtls1
+.Op Fl dtls1_2
 .Op Fl groups Ar list
 .Op Fl HTTP
 .Op Fl id_prefix Ar arg
@@ -4754,8 +4762,12 @@ load the parameters from the server certificate file.
 If this fails, a static set of parameters hard coded into the
 .Nm s_server
 program will be used.
+.It Fl dtls
+Permit any version of DTLS.
 .It Fl dtls1
 Permit only DTLS1.0.
+.It Fl dtls1_2
+Permit only DTLS1.2.
 .It Fl groups Ar list
 Set the supported elliptic curve groups to the colon separated
 .Ar list
index eeeecff..f03f8a9 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: s_client.c,v 1.52 2020/10/14 05:36:18 tb Exp $ */
+/* $OpenBSD: s_client.c,v 1.53 2021/03/17 18:08:32 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -260,7 +260,7 @@ s_client_opt_keymatexportlen(char *arg)
        return (0);
 }
 
-#ifndef OPENSSL_NO_DTLS1
+#ifndef OPENSSL_NO_DTLS
 static int
 s_client_opt_mtu(char *arg)
 {
@@ -285,11 +285,35 @@ s_client_opt_port(char *arg)
        return (0);
 }
 
+#ifndef OPENSSL_NO_DTLS
+static int
+s_client_opt_protocol_version_dtls(void)
+{
+       s_client_config.meth = DTLS_client_method();
+       s_client_config.socket_type = SOCK_DGRAM;
+       return (0);
+}
+#endif
+
 #ifndef OPENSSL_NO_DTLS1
 static int
 s_client_opt_protocol_version_dtls1(void)
 {
        s_client_config.meth = DTLS_client_method();
+       s_client_config.min_version = DTLS1_VERSION;
+       s_client_config.max_version = DTLS1_VERSION;
+       s_client_config.socket_type = SOCK_DGRAM;
+       return (0);
+}
+#endif
+
+#ifndef OPENSSL_NO_DTLS1_2
+static int
+s_client_opt_protocol_version_dtls1_2(void)
+{
+       s_client_config.meth = DTLS_client_method();
+       s_client_config.min_version = DTLS1_2_VERSION;
+       s_client_config.max_version = DTLS1_2_VERSION;
        s_client_config.socket_type = SOCK_DGRAM;
        return (0);
 }
@@ -472,6 +496,14 @@ static const struct option s_client_options[] = {
                .type = OPTION_FLAG,
                .opt.flag = &s_client_config.debug,
        },
+#ifndef OPENSSL_NO_DTLS
+       {
+               .name = "dtls",
+               .desc = "Use any version of DTLS",
+               .type = OPTION_FUNC,
+               .opt.func = s_client_opt_protocol_version_dtls,
+       },
+#endif
 #ifndef OPENSSL_NO_DTLS1
        {
                .name = "dtls1",
@@ -479,6 +511,14 @@ static const struct option s_client_options[] = {
                .type = OPTION_FUNC,
                .opt.func = s_client_opt_protocol_version_dtls1,
        },
+#endif
+#ifndef OPENSSL_NO_DTLS1_2
+       {
+               .name = "dtls1_2",
+               .desc = "Just use DTLSv1.2",
+               .type = OPTION_FUNC,
+               .opt.func = s_client_opt_protocol_version_dtls1_2,
+       },
 #endif
        {
                .name = "groups",
@@ -546,7 +586,7 @@ static const struct option s_client_options[] = {
                .type = OPTION_FLAG,
                .opt.flag = &s_client_config.msg,
        },
-#ifndef OPENSSL_NO_DTLS1
+#ifndef OPENSSL_NO_DTLS
        {
                .name = "mtu",
                .argname = "mtu",
@@ -745,7 +785,7 @@ static const struct option s_client_options[] = {
                .type = OPTION_FLAG,
                .opt.flag = &s_client_config.status_req,
        },
-#ifndef OPENSSL_NO_DTLS1
+#ifndef OPENSSL_NO_DTLS
        {
                .name = "timeout",
                .desc = "Enable send/receive timeout on DTLS connections",
@@ -828,7 +868,7 @@ sc_usage(void)
            "[-4 | -6] [-alpn protocols] [-bugs] [-CAfile file]\n"
            "    [-CApath directory] [-cert file] [-certform der | pem] [-check_ss_sig]\n"
            "    [-cipher cipherlist] [-connect host[:port]] [-crl_check]\n"
-           "    [-crl_check_all] [-crlf] [-debug] [-dtls1] [-extended_crl]\n"
+           "    [-crl_check_all] [-crlf] [-debug] [-dtls] [-dtls1] [-dtls1_2] [-extended_crl]\n"
            "    [-groups list] [-host host] [-ign_eof] [-ignore_critical]\n"
            "    [-issuer_checks] [-key keyfile] [-keyform der | pem]\n"
            "    [-keymatexport label] [-keymatexportlen len] [-legacy_server_connect]\n"
@@ -1090,8 +1130,7 @@ s_client_main(int argc, char **argv)
        if (s_client_config.pause & 0x01)
                SSL_set_debug(con, 1);
 
-       if (SSL_version(con) == DTLS1_VERSION) {
-
+       if (SSL_is_dtls(con)) {
                sbio = BIO_new_dgram(s, BIO_NOCLOSE);
                if (getsockname(s, (struct sockaddr *)&peer,
                    (void *)&peerlen) == -1) {
@@ -1290,8 +1329,7 @@ s_client_main(int argc, char **argv)
                struct pollfd pfd[3];   /* stdin, stdout, socket */
                int ptimeout = -1;
 
-               if ((SSL_version(con) == DTLS1_VERSION) &&
-                   DTLSv1_get_timeout(con, &timeout))
+               if (SSL_is_dtls(con) && DTLSv1_get_timeout(con, &timeout))
                        ptimeout = timeout.tv_sec * 1000 +
                            timeout.tv_usec / 1000;
 
@@ -1370,10 +1408,9 @@ s_client_main(int argc, char **argv)
                                /* goto end; */
                        }
                }
-               if ((SSL_version(con) == DTLS1_VERSION) &&
-                   DTLSv1_handle_timeout(con) > 0) {
+               if (SSL_is_dtls(con) &&
+                   DTLSv1_handle_timeout(con) > 0)
                        BIO_printf(bio_err, "TIMEOUT occured\n");
-               }
                if (!ssl_pending &&
                    (pfd[2].revents & (POLLOUT|POLLERR|POLLNVAL))) {
                        if (pfd[2].revents & (POLLERR|POLLNVAL)) {
index 4d4bed6..6009b58 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: s_server.c,v 1.44 2020/10/02 15:43:48 tb Exp $ */
+/* $OpenBSD: s_server.c,v 1.45 2021/03/17 18:08:32 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -239,7 +239,7 @@ static struct {
        int bugs;
        char *CAfile;
        char *CApath;
-#ifndef OPENSSL_NO_DTLS1
+#ifndef OPENSSL_NO_DTLS
        int cert_chain;
 #endif
        char *cert_file;
@@ -315,7 +315,7 @@ s_server_opt_keymatexportlen(char *arg)
        return (0);
 }
 
-#ifndef OPENSSL_NO_DTLS1
+#ifndef OPENSSL_NO_DTLS
 static int
 s_server_opt_mtu(char *arg)
 {
@@ -328,9 +328,11 @@ s_server_opt_mtu(char *arg)
        }
        return (0);
 }
+#endif
 
+#ifndef OPENSSL_NO_DTLS
 static int
-s_server_protocol_version_dtls1(void)
+s_server_opt_protocol_version_dtls(void)
 {
        s_server_config.meth = DTLS_server_method();
        s_server_config.socket_type = SOCK_DGRAM;
@@ -338,6 +340,30 @@ s_server_protocol_version_dtls1(void)
 }
 #endif
 
+#ifndef OPENSSL_NO_DTLS1
+static int
+s_server_opt_protocol_version_dtls1(void)
+{
+       s_server_config.meth = DTLS_server_method();
+       s_server_config.min_version = DTLS1_VERSION;
+       s_server_config.max_version = DTLS1_VERSION;
+       s_server_config.socket_type = SOCK_DGRAM;
+       return (0);
+}
+#endif
+
+#ifndef OPENSSL_NO_DTLS1_2
+static int
+s_server_opt_protocol_version_dtls1_2(void)
+{
+       s_server_config.meth = DTLS_server_method();
+       s_server_config.min_version = DTLS1_2_VERSION;
+       s_server_config.max_version = DTLS1_2_VERSION;
+       s_server_config.socket_type = SOCK_DGRAM;
+       return (0);
+}
+#endif
+
 static int
 s_server_protocol_version_tls1(void)
 {
@@ -538,7 +564,7 @@ static const struct option s_server_options[] = {
                .type = OPTION_ARG_FORMAT,
                .opt.value = &s_server_config.cert_format,
        },
-#ifndef OPENSSL_NO_DTLS1
+#ifndef OPENSSL_NO_DTLS
        {
                .name = "chain",
                .type = OPTION_FLAG,
@@ -613,12 +639,28 @@ static const struct option s_server_options[] = {
                .type = OPTION_ARG,
                .opt.arg = &s_server_config.dpassarg,
        },
+#ifndef OPENSSL_NO_DTLS
+       {
+               .name = "dtls",
+               .desc = "Use any version of DTLS",
+               .type = OPTION_FUNC,
+               .opt.func = s_server_opt_protocol_version_dtls,
+       },
+#endif
 #ifndef OPENSSL_NO_DTLS1
        {
                .name = "dtls1",
-               .desc = "Just talk DTLSv1",
+               .desc = "Just use DTLSv1",
                .type = OPTION_FUNC,
-               .opt.func = s_server_protocol_version_dtls1,
+               .opt.func = s_server_opt_protocol_version_dtls1,
+       },
+#endif
+#ifndef OPENSSL_NO_DTLS1_2
+       {
+               .name = "dtls1_2",
+               .desc = "Just use DTLSv1.2",
+               .type = OPTION_FUNC,
+               .opt.func = s_server_opt_protocol_version_dtls1_2,
        },
 #endif
        {
@@ -689,7 +731,7 @@ static const struct option s_server_options[] = {
                .type = OPTION_FLAG,
                .opt.flag = &s_server_config.msg,
        },
-#ifndef OPENSSL_NO_DTLS1
+#ifndef OPENSSL_NO_DTLS
        {
                .name = "mtu",
                .argname = "mtu",
@@ -876,7 +918,7 @@ static const struct option s_server_options[] = {
                .type = OPTION_FUNC,
                .opt.func = s_server_opt_status_verbose,
        },
-#ifndef OPENSSL_NO_DTLS1
+#ifndef OPENSSL_NO_DTLS
        {
                .name = "timeout",
                .desc = "Enable timeouts",
@@ -1000,7 +1042,7 @@ sv_usage(void)
            "    [-context id] [-crl_check] [-crl_check_all] [-crlf]\n"
            "    [-dcert file] [-dcertform der | pem] [-debug]\n"
            "    [-dhparam file] [-dkey file] [-dkeyform der | pem]\n"
-           "    [-dpass arg] [-dtls1] [-groups list] [-HTTP]\n"
+           "    [-dpass arg] [-dtls] [-dtls1] [-dtls1_2] [-groups list] [-HTTP]\n"
            "    [-id_prefix arg] [-key keyfile] [-key2 keyfile]\n"
            "    [-keyform der | pem] [-keymatexport label]\n"
            "    [-keymatexportlen len] [-msg] [-mtu mtu]\n"
@@ -1535,8 +1577,7 @@ sv_body(char *hostname, int s, unsigned char *context)
        }
        SSL_clear(con);
 
-       if (SSL_version(con) == DTLS1_VERSION) {
-
+       if (SSL_is_dtls(con)) {
                sbio = BIO_new_dgram(s, BIO_NOCLOSE);
 
                if (s_server_config.enable_timeouts) {
@@ -1602,7 +1643,7 @@ sv_body(char *hostname, int s, unsigned char *context)
                        pfd[1].fd = s;
                        pfd[1].events = POLLIN;
 
-                       if ((SSL_version(con) == DTLS1_VERSION) &&
+                       if (SSL_is_dtls(con) &&
                            DTLSv1_get_timeout(con, &timeout))
                                ptimeout = timeout.tv_sec * 1000 +
                                    timeout.tv_usec / 1000;
@@ -1611,10 +1652,9 @@ sv_body(char *hostname, int s, unsigned char *context)
 
                        i = poll(pfd, 2, ptimeout);
 
-                       if ((SSL_version(con) == DTLS1_VERSION) &&
-                           DTLSv1_handle_timeout(con) > 0) {
+                       if (SSL_is_dtls(con) &&
+                           DTLSv1_handle_timeout(con) > 0)
                                BIO_printf(bio_err, "TIMEOUT occured\n");
-                       }
                        if (i <= 0)
                                continue;
                        if (pfd[0].revents) {
@@ -1660,7 +1700,7 @@ sv_body(char *hostname, int s, unsigned char *context)
                                }
                                if ((i <= 0) || (buf[0] == 'q')) {
                                        BIO_printf(bio_s_out, "DONE\n");
-                                       if (SSL_version(con) != DTLS1_VERSION) {
+                                       if (!SSL_is_dtls(con)) {
                                                shutdown(s, SHUT_RD);
                                                close(s);
                                        }