cron2 has submitted this change. ( http://gerrit.openvpn.net/c/openvpn/+/1304?usp=email )
Change subject: Add option to check tls-crypt-v2 key timestamps ...................................................................... Add option to check tls-crypt-v2 key timestamps This commit adds the option --tls-crypt-v2-max-age n. When a client key is older than n days or has no timestamp, the server rejects it. Based on work by Rein van Baaren for Sentyron. Co-authored-by: Rein van Baaren <[email protected]> Change-Id: I0579d18c784e2ac16973d5553992c28f281a0900 Signed-off-by: Max Fillinger <[email protected]> Acked-by: Arne Schwabe <[email protected]> Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1304 Message-Id: <[email protected]> URL: https://www.mail-archive.com/[email protected]/msg34545.html Signed-off-by: Gert Doering <[email protected]> --- M doc/man-sections/tls-options.rst M doc/tls-crypt-v2.txt M src/openvpn/init.c M src/openvpn/options.c M src/openvpn/options.h M src/openvpn/ssl_common.h M src/openvpn/tls_crypt.c 7 files changed, 57 insertions(+), 1 deletion(-) diff --git a/doc/man-sections/tls-options.rst b/doc/man-sections/tls-options.rst index db107e6..63cb32f 100644 --- a/doc/man-sections/tls-options.rst +++ b/doc/man-sections/tls-options.rst @@ -568,6 +568,10 @@ The command can reject the connection by exiting with a non-zero exit code. +--tls-crypt-v2-max-age n + Reject tls-crypt-v2 client keys that are older than n days or have + no timestamp. + --tls-exit Exit on TLS negotiation failure. This option can be useful when you only want to make one attempt at connecting, e.g. in a test or monitoring script. diff --git a/doc/tls-crypt-v2.txt b/doc/tls-crypt-v2.txt index 7dcd041..c2e9deb 100644 --- a/doc/tls-crypt-v2.txt +++ b/doc/tls-crypt-v2.txt @@ -139,7 +139,10 @@ The message is dropped and no error response is sent when either 3.1, 3.2 or 3.3 fails (DoS protection). -4. Server optionally checks metadata using a --tls-crypt-v2-verify script +4. The server optionally checks if the client key contains a timestamp that is + below a maximum age configured with the --tls-crypt-v2-max-age option. + +5. Server optionally checks metadata using a --tls-crypt-v2-verify script This allows early abort of connection, *before* we expose any of the notoriously dangerous TLS, X.509 and ASN.1 parsers and thereby reduces the diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 8d95d5c..fc079e1 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -3418,6 +3418,7 @@ { to.tls_wrap.tls_crypt_v2_server_key = c->c1.ks.tls_crypt_v2_server_key; to.tls_crypt_v2_verify_script = c->options.tls_crypt_v2_verify_script; + to.tls_crypt_v2_max_age = c->options.tls_crypt_v2_max_age; if (options->ce.tls_crypt_v2_force_cookie) { to.tls_wrap.opt.flags |= CO_FORCE_TLSCRYPTV2_COOKIE; diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 683543a..4794315 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -648,6 +648,8 @@ " fresh tls-crypt-v2 server key, and store to keyfile\n" "--tls-crypt-v2-verify cmd : Run command cmd to verify the metadata of the\n" " client-supplied tls-crypt-v2 client key\n" + "--tls-crypt-v2-max-age n : Only accept tls-crypt-v2 client keys that have a\n" + " timestamp which is at most n days old.\n" "--askpass [file]: Get PEM password from controlling tty before we daemonize.\n" "--auth-nocache : Don't cache --askpass or --auth-user-pass passwords.\n" "--crl-verify crl ['dir']: Check peer certificate against a CRL.\n" @@ -9079,6 +9081,14 @@ VERIFY_PERMISSION(OPT_P_GENERAL); options->tls_crypt_v2_verify_script = p[1]; } + else if (streq(p[0], "tls-crypt-v2-max-age") && p[1]) + { + VERIFY_PERMISSION(OPT_P_GENERAL); + if (!atoi_constrained(p[1], &options->tls_crypt_v2_max_age, "tls-crypt-v2-max-age", 1, INT_MAX, msglevel)) + { + goto err; + } + } else if (streq(p[0], "x509-track") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_GENERAL); diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 9d2ff9f..42db9ca 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -678,6 +678,8 @@ const char *tls_crypt_v2_verify_script; + int tls_crypt_v2_max_age; + /* Allow only one session */ bool single_session; diff --git a/src/openvpn/ssl_common.h b/src/openvpn/ssl_common.h index 23da8cf..3129299 100644 --- a/src/openvpn/ssl_common.h +++ b/src/openvpn/ssl_common.h @@ -383,6 +383,7 @@ bool tls_crypt_v2; const char *tls_crypt_v2_verify_script; + int tls_crypt_v2_max_age; /** TLS handshake wrapping state */ struct tls_wrap_ctx tls_wrap; diff --git a/src/openvpn/tls_crypt.c b/src/openvpn/tls_crypt.c index ab719b3..318c939 100644 --- a/src/openvpn/tls_crypt.c +++ b/src/openvpn/tls_crypt.c @@ -29,6 +29,7 @@ #include "argv.h" #include "base64.h" #include "crypto.h" +#include "integer.h" #include "platform.h" #include "run_command.h" #include "session_id.h" @@ -520,6 +521,34 @@ } static bool +tls_crypt_v2_check_client_key_age(const struct tls_wrap_ctx *ctx, int max_days) +{ + if (ctx->tls_crypt_v2_metadata.len < 1 + sizeof(int64_t)) + { + msg(M_WARN, "ERROR: Client key metadata is too small to contain a timestamp."); + return false; + } + + const uint8_t *metadata = ctx->tls_crypt_v2_metadata.data; + if (*metadata != TLS_CRYPT_METADATA_TYPE_TIMESTAMP) + { + msg(M_WARN, "ERROR: Client key does not have a timestamp."); + return false; + } + + int64_t timestamp; + memcpy(×tamp, metadata + 1, sizeof(int64_t)); + timestamp = (int64_t)ntohll((uint64_t)timestamp); + int64_t max_age_in_seconds = max_days * 24 * 60 * 60; + if (now - timestamp > max_age_in_seconds) + { + msg(M_WARN, "ERROR: Client key is too old."); + return false; + } + return true; +} + +static bool tls_crypt_v2_verify_metadata(const struct tls_wrap_ctx *ctx, const struct tls_options *opt) { bool ret = false; @@ -634,6 +663,12 @@ return false; } + if (opt && opt->tls_crypt_v2_max_age > 0 && !tls_crypt_v2_check_client_key_age(ctx, opt->tls_crypt_v2_max_age)) + { + secure_memzero(&ctx->original_wrap_keydata, sizeof(ctx->original_wrap_keydata)); + return false; + } + if (opt && opt->tls_crypt_v2_verify_script && !tls_crypt_v2_verify_metadata(ctx, opt)) { secure_memzero(&ctx->original_wrap_keydata, sizeof(ctx->original_wrap_keydata)); -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1304?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings?usp=email Gerrit-MessageType: merged Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I0579d18c784e2ac16973d5553992c28f281a0900 Gerrit-Change-Number: 1304 Gerrit-PatchSet: 7 Gerrit-Owner: MaxF <[email protected]> Gerrit-Reviewer: flichtenheld <[email protected]> Gerrit-Reviewer: plaisthos <[email protected]> Gerrit-CC: openvpn-devel <[email protected]>
_______________________________________________ Openvpn-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openvpn-devel
