From abe0bb1a7f727a24e2d7cb7215cb309aea5fcffc Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Wed, 1 Dec 2021 19:07:19 +0100 Subject: [PATCH] Implement optional cipher in --data-ciphers prefixed with ? This allows to use the same configuration multiple platforms/ssl libraries and include optional algorithms that are not available on all platforms For example "AES-256-GCM:AES-128-GCM:?CHACHA20-POLY1305" can be used to emulate the default behaviour of OpenVPN 2.6. Signed-off-by: Arne Schwabe Acked-by: Gert Doering Message-Id: <20211201180727.2496903-1-arne@rfc2549.org> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg23279.html Signed-off-by: Gert Doering (cherry picked from commit 766044507497c41f0319159c37992788ecb681e6) --- Changes.rst | 9 +++++++++ doc/man-sections/protocol-options.rst | 7 +++++++ src/openvpn/ssl_ncp.c | 16 ++++++++++++++-- tests/unit_tests/openvpn/test_ncp.c | 11 +++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/Changes.rst b/Changes.rst index cafb1f23f..ec7045dae 100644 --- a/Changes.rst +++ b/Changes.rst @@ -1,3 +1,12 @@ +Overview of changes in 2.5.9 +============================ + +New features +------------ +- Optional ciphers in ``--data-ciphers`` + Ciphers in ``--data-ciphers`` can now be prefixed with a ``?`` to mark + those as optional and only use them if the SSL library supports them. + Overview of changes in 2.5.8 ============================ diff --git a/doc/man-sections/protocol-options.rst b/doc/man-sections/protocol-options.rst index e9d5d63d4..25f8db12d 100644 --- a/doc/man-sections/protocol-options.rst +++ b/doc/man-sections/protocol-options.rst @@ -184,6 +184,13 @@ configured in a compatible way between both the local and remote side. supported by the client will be pushed to clients that support cipher negotiation. + Starting with OpenVPN 2.5.9 a cipher can be prefixed with a :code:`?` to mark + it as optional. This allows including ciphers in the list that may not be + available on all platforms. + E.g. :code:`AES-256-GCM:AES-128-GCM:?CHACHA20-POLY1305` would only enable + Chacha20-Poly1305 if the underlying SSL library (and its configuration) + supports it. + Cipher negotiation is enabled in client-server mode only. I.e. if ``--mode`` is set to 'server' (server-side, implied by setting ``--server`` ), or if ``--pull`` is specified (client-side, implied by diff --git a/src/openvpn/ssl_ncp.c b/src/openvpn/ssl_ncp.c index b94c786ee..de7efa407 100644 --- a/src/openvpn/ssl_ncp.c +++ b/src/openvpn/ssl_ncp.c @@ -108,7 +108,18 @@ mutate_ncp_cipher_list(const char *list, struct gc_arena *gc) * (and translate_cipher_name_from_openvpn/ * translate_cipher_name_to_openvpn) also normalises the cipher name, * e.g. replacing AeS-128-gCm with AES-128-GCM + * + * ciphers that have ? in front of them are considered optional and + * OpenVPN will only warn if they are not found (and remove them from + * the list) */ + + bool optional = false; + if (token[0] == '?') + { + token++; + optional = true; + } const cipher_kt_t *ktc = cipher_kt_get(token); if (strcmp(token, "none") == 0) { @@ -120,8 +131,9 @@ mutate_ncp_cipher_list(const char *list, struct gc_arena *gc) } if (!ktc && strcmp(token, "none") != 0) { - msg(M_WARN, "Unsupported cipher in --data-ciphers: %s", token); - error_found = true; + const char* optstr = optional ? "optional ": ""; + msg(M_WARN, "Unsupported %scipher in --data-ciphers: %s", optstr, token); + error_found = !optional; } else { diff --git a/tests/unit_tests/openvpn/test_ncp.c b/tests/unit_tests/openvpn/test_ncp.c index 4337f6df7..134a58ab6 100644 --- a/tests/unit_tests/openvpn/test_ncp.c +++ b/tests/unit_tests/openvpn/test_ncp.c @@ -74,6 +74,17 @@ test_check_ncp_ciphers_list(void **state) assert_ptr_equal(mutate_ncp_cipher_list(bf_chacha, &gc), NULL); } + /* Check that optional ciphers work */ + assert_string_equal(mutate_ncp_cipher_list("AES-256-GCM:?vollbit:AES-128-GCM", &gc), + aes_ciphers); + + /* Check that optional ciphers work */ + assert_string_equal(mutate_ncp_cipher_list("?AES-256-GCM:?AES-128-GCM", &gc), + aes_ciphers); + + /* All unsupported should still yield an empty list */ + assert_ptr_equal(mutate_ncp_cipher_list("?kugelfisch:?grasshopper", &gc), NULL); + /* For testing that with OpenSSL 1.1.0+ that also accepts ciphers in * a different spelling the normalised cipher output is the same */ bool have_chacha_mixed_case = cipher_kt_get("ChaCha20-Poly1305"); -- 2.47.3