|
From: MaxF (C. Review) <ge...@op...> - 2025-10-27 09:55:30
|
Attention is currently required from: flichtenheld, plaisthos.
Hello flichtenheld, plaisthos,
I'd like you to reexamine a change. Please visit
http://gerrit.openvpn.net/c/openvpn/+/1304?usp=email
to look at the new patch set (#4).
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 <rev...@pr...>
Change-Id: I0579d18c784e2ac16973d5553992c28f281a0900
Signed-off-by: Max Fillinger <ma...@ma...>
---
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, 49 insertions(+), 1 deletion(-)
git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/04/1304/4
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 aa2611d..a6331dc 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -3442,6 +3442,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 65c6b3b..2cdf58f 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -653,6 +653,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"
@@ -9087,6 +9089,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 009904a..9329030 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -682,6 +682,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 de89d30..0402a6a 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 51b4eb3..83355f9 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"
@@ -528,6 +529,27 @@
}
static bool
+tls_crypt_v2_check_client_key_age(const struct tls_wrap_ctx *ctx, int max_days)
+{
+ const uint8_t *metadata = ctx->tls_crypt_v2_metadata.data;
+ if (*metadata != TLS_CRYPT_METADATA_TYPE_TIMESTAMP)
+ {
+ msg(M_WARN, "ERROR: Client key doesn't 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;
@@ -652,6 +674,11 @@
/* Remove client key from buffer so tls-crypt code can unwrap message */
ASSERT(buf_inc_len(buf, -(BLEN(&wrapped_client_key))));
+ if (opt && opt->tls_crypt_v2_max_age > 0 && !tls_crypt_v2_check_client_key_age(ctx, opt->tls_crypt_v2_max_age))
+ {
+ return false;
+ }
+
if (opt && opt->tls_crypt_v2_verify_script)
{
return tls_crypt_v2_verify_metadata(ctx, opt);
--
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: newpatchset
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I0579d18c784e2ac16973d5553992c28f281a0900
Gerrit-Change-Number: 1304
Gerrit-PatchSet: 4
Gerrit-Owner: MaxF <ma...@ma...>
Gerrit-Reviewer: flichtenheld <fr...@li...>
Gerrit-Reviewer: plaisthos <arn...@rf...>
Gerrit-CC: openvpn-devel <ope...@li...>
Gerrit-Attention: plaisthos <arn...@rf...>
Gerrit-Attention: flichtenheld <fr...@li...>
|