Re: [Openvpn-devel] [PATCH v6 5/5] Normalise ncp-ciphers option and restrict it to 127 bytes

2020-03-27 Thread David Sommerseth
On 12/03/2020 12:36, Arne Schwabe wrote:
> In scenarios of mbed TLS vs OpenSSL we already normalise the ciphers
> that are send via the wire protocol via OCC to not have a mismatch
> warning between server and client. This is done by
> translate_cipher_name_from_openvpn. The same applies also to the
> ncp-ciphers list. Specifying non normalised names in ncp-ciphers will
> cause negotation not to succeed if ciphers are not in the same form.
> Therefore we will normalise the ciphers in options_postmutate.
> 
> The alternative and a lot less user friendly alternative would be to
> bail if on of the ciphers in ncp-ciphers is not in its normalised form.
> 
> Also restrict the ncp-ciphers list to 127. This is somewhat arbitrary
> but should prevent too large IV_CIPHER messages and problems sending
> those. The server will accept also large IV_CIPHER values from clients.
> 
> Patch V2: Correct comment about normalising ciphers
> Patch V3: Correct #ifdef statement
> Patch V5: Fix tests with OpenSSL 1.0.2 and libraries missing Chacha
> Patch V6: Fix unit tests for mbed tls, which recognises ChaCha20-Poly1305
>   only when used with all uppercase, fix missing space in message
> 
> Signed-off-by: Arne Schwabe 
> ---
>  doc/openvpn.8   |  3 ++
>  src/openvpn/options.c   | 14 ---
>  src/openvpn/ssl_ncp.c   | 57 +
>  src/openvpn/ssl_ncp.h   | 19 +-
>  tests/unit_tests/openvpn/test_ncp.c | 54 +++
>  5 files changed, 125 insertions(+), 22 deletions(-)
> 

I've only done quick code review and built it on RHEL7 not finding any issues.
 Code looks reasonable, so I don't see any reason to hold this back any more.

Acked-by: David Sommerseth 

-- 
kind regards,

David Sommerseth
OpenVPN Inc




signature.asc
Description: OpenPGP digital signature
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH v6 5/5] Normalise ncp-ciphers option and restrict it to 127 bytes

2020-03-12 Thread Arne Schwabe
In scenarios of mbed TLS vs OpenSSL we already normalise the ciphers
that are send via the wire protocol via OCC to not have a mismatch
warning between server and client. This is done by
translate_cipher_name_from_openvpn. The same applies also to the
ncp-ciphers list. Specifying non normalised names in ncp-ciphers will
cause negotation not to succeed if ciphers are not in the same form.
Therefore we will normalise the ciphers in options_postmutate.

The alternative and a lot less user friendly alternative would be to
bail if on of the ciphers in ncp-ciphers is not in its normalised form.

Also restrict the ncp-ciphers list to 127. This is somewhat arbitrary
but should prevent too large IV_CIPHER messages and problems sending
those. The server will accept also large IV_CIPHER values from clients.

Patch V2: Correct comment about normalising ciphers
Patch V3: Correct #ifdef statement
Patch V5: Fix tests with OpenSSL 1.0.2 and libraries missing Chacha
Patch V6: Fix unit tests for mbed tls, which recognises ChaCha20-Poly1305
  only when used with all uppercase, fix missing space in message

Signed-off-by: Arne Schwabe 
---
 doc/openvpn.8   |  3 ++
 src/openvpn/options.c   | 14 ---
 src/openvpn/ssl_ncp.c   | 57 +
 src/openvpn/ssl_ncp.h   | 19 +-
 tests/unit_tests/openvpn/test_ncp.c | 54 +++
 5 files changed, 125 insertions(+), 22 deletions(-)

diff --git a/doc/openvpn.8 b/doc/openvpn.8
index 864f94e8..c5b16981 100644
--- a/doc/openvpn.8
+++ b/doc/openvpn.8
@@ -4406,6 +4406,9 @@ AES\-256\-GCM:AES\-256\-CBC" set can either specify 
"\-\-cipher BF\-CBC" or
 
 Note, for using NCP with a OpenVPN 2.4 peer this list must include
 the AES\-256\-GCM and AES\-128\-GCM ciphers.
+
+This list is restricted to be 127 chars long after conversion to OpenVPN
+ciphers.
 .\"*
 .TP
 .B \-\-ncp\-disable
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index e79a1215..5127f653 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -2516,11 +2516,6 @@ options_postprocess_verify_ce(const struct options 
*options, const struct connec
 }
 #endif /* P2MP_SERVER */
 
-if (options->ncp_enabled && 
!tls_check_ncp_cipher_list(options->ncp_ciphers))
-{
-msg(M_USAGE, "NCP cipher list contains unsupported ciphers.");
-}
-
 if (options->keysize)
 {
 msg(M_WARN, "WARNING: --keysize is DEPRECATED and will be removed in 
OpenVPN 2.6");
@@ -3098,6 +3093,15 @@ options_postprocess_mutate(struct options *o)
 
 options_postprocess_mutate_invariant(o);
 
+if (o->ncp_enabled)
+{
+o->ncp_ciphers = mutate_ncp_cipher_list(o->ncp_ciphers, >gc);
+if (o->ncp_ciphers == NULL)
+{
+msg(M_USAGE, "NCP cipher list contains unsupported ciphers or is 
too long.");
+}
+}
+
 if (o->remote_list && !o->connection_list)
 {
 /*
diff --git a/src/openvpn/ssl_ncp.c b/src/openvpn/ssl_ncp.c
index d884e2b5..9ed6ff5f 100644
--- a/src/openvpn/ssl_ncp.c
+++ b/src/openvpn/ssl_ncp.c
@@ -91,27 +91,70 @@ tls_peer_supports_ncp(const char *peer_info)
 }
 }
 
-bool
-tls_check_ncp_cipher_list(const char *list)
+char *
+mutate_ncp_cipher_list(const char *list, struct gc_arena *gc)
 {
-bool unsupported_cipher_found = false;
+bool error_found = false;
 
-ASSERT(list);
+struct buffer new_list  = alloc_buf(MAX_NCP_CIPHERS_LENGTH);
 
 char *const tmp_ciphers = string_alloc(list, NULL);
 const char *token = strtok(tmp_ciphers, ":");
 while (token)
 {
-if (!cipher_kt_get(translate_cipher_name_from_openvpn(token)))
+/*
+ * Going through a roundtrip by using 
translate_cipher_name_from_openvpn
+ * and translate_cipher_name_to_openvpn also normalises the cipher 
name,
+ * e.g. replacing AeS-128-gCm with AES-128-GCM
+ */
+const char *cipher_name = translate_cipher_name_from_openvpn(token);
+const cipher_kt_t *ktc = cipher_kt_get(cipher_name);
+if (!ktc)
 {
 msg(M_WARN, "Unsupported cipher in --ncp-ciphers: %s", token);
-unsupported_cipher_found = true;
+error_found = true;
+}
+else
+{
+const char *ovpn_cipher_name =
+translate_cipher_name_to_openvpn(cipher_kt_name(ktc));
+
+if (buf_len(_list)> 0)
+{
+/* The next if condition ensure there is always space for
+ * a :
+ */
+buf_puts(_list, ":");
+}
+
+/* Ensure buffer has capacity for cipher name + : + \0 */
+if (!(buf_forward_capacity(_list) >
+  strlen(ovpn_cipher_name) + 2))
+{
+msg(M_WARN, "Length of --ncp-ciphers is over the "
+"limit of 127 chars");