@@ -58,6 +58,10 @@ OpenSSL 3.0 support
(and other deprecated) algorithm by default and the new option ``--providers``
allows loading the legacy provider to renable these algorithms.
+Optional ciphers in ``--data-ciphers``
+ Ciphers in ``--data-ciphers`` can now be prefixes with a ``?`` to mark
+ those as optional and only use them if the SSL library supports them.
+
Deprecated features
-------------------
``inetd`` has been removed
@@ -204,6 +204,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.6 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
@@ -109,7 +109,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= token + 1;
+ optional = true;
+ }
const cipher_kt_t *ktc = cipher_kt_get(token);
if (strcmp(token, "none") == 0)
{
@@ -121,8 +132,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
{
@@ -84,6 +84,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");