options_postprocess_mutate_invariant(o);
+ if (o->ncp_enabled)
+ {
+ o->ncp_ciphers = mutate_ncp_cipher_list(o->ncp_ciphers, &o->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)
{
/*
purge_user_pass(&auth_user_pass, false);
}
+char *
+mutate_ncp_cipher_list(const char *list, struct gc_arena *gc)
+{
+ bool error_found = false;
+
+ 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)
+ {
+ /*
+ * 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);
+ error_found = true;
+ }
+ else
+ {
+ const char *ovpn_cipher_name =
+ translate_cipher_name_to_openvpn(cipher_kt_name(ktc));
+
+ if (buf_len(&new_list)> 0)
+ {
+ /* The next if condition ensure there is always space for
+ * a :
+ */
+ buf_puts(&new_list, ":");
+ }
+
+ /* Ensure buffer has capacity for cipher name + : + \0 */
+ if (!(buf_forward_capacity(&new_list) >
+ strlen(ovpn_cipher_name) + 2))
+ {
+ msg(M_WARN, "Length of --ncp-ciphers is over the "
+ "limit of 127 chars");
+ error_found = true;
+ }
+ else
+ {
+ buf_puts(&new_list, ovpn_cipher_name);
+ }
+ }
+ token = strtok(NULL, ":");
+ }
+
+ char *ret = NULL;
+ if (!error_found && buf_len(&new_list) > 0)
+ {
+ buf_null_terminate(&new_list);
+ ret = string_alloc(buf_str(&new_list), gc);
+ }
+ free(tmp_ciphers);
+ free_buf(&new_list);
+
+ return ret;
+}
#else /* if defined(ENABLE_CRYPTO) */
static void
dummy(void)
*/
bool tls_item_in_cipher_list(const char *item, const char *list);
+/**
+ * Check whether the ciphers in the supplied list are supported.
+ *
+ * @param list Colon-separated list of ciphers
+ * @parms gc gc_arena to allocate the returned string
+ *
+ * @returns colon separated string of normalised (via
+ * translate_cipher_name_from_openvpn) and
+ * zero terminated string iff all ciphers
+ * in list are supported and the total length
+ * is short than MAX_NCP_CIPHERS_LENGTH. NULL
+ * otherwise.
+ */
+char *
+mutate_ncp_cipher_list(const char *list, struct gc_arena *gc);
+
+/**
+ * The maximum length of a ncp-cipher string that is accepted.
+ *
+ * Since this list needs to be pushed as IV_CIPHERS, we are conservative
+ * about its length.
+ */
+#define MAX_NCP_CIPHERS_LENGTH 127
/*
* inline functions