Attention is currently required from: plaisthos, ralf_lici, stipa.
Hello plaisthos, ralf_lici,
I'd like you to reexamine a change. Please visit
http://gerrit.openvpn.net/c/openvpn/+/1759?usp=email
to look at the new patch set (#29).
Change subject: oob: Send tls-crypt-v2 probe requests from the client
......................................................................
oob: Send tls-crypt-v2 probe requests from the client
When tls-crypt-v2 is configured, send the probe as P_CONTROL_OOB_WKC_V1
with the wrapped client key (WKc) appended, so the server can recover
the per-client key and unwrap it. Without tls-crypt-v2 the probe stays a
plain P_CONTROL_OOB_V1, unchanged.
- drop the "skip probing under tls-crypt-v2" bail-out
- make the WKc available on the probe's wrap context (mirroring
do_init_crypto_tls()), so tls_wrap_control() appends it, and free it
with the rest of the probe's key material
- choose the opcode (P_CONTROL_OOB_WKC_V1 vs P_CONTROL_OOB_V1) and
report "tls-crypt-v2" in the wrapping log line
Change-Id: I5cc100dd7dc810d7d1e6f29bb57584905fbcf4a0
Signed-off-by: Lev Stipakov <[email protected]>
---
M doc/man-sections/client-options.rst
M src/openvpn/oob_client.c
2 files changed, 26 insertions(+), 27 deletions(-)
git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/59/1759/29
diff --git a/doc/man-sections/client-options.rst
b/doc/man-sections/client-options.rst
index 7749f37..370ef60 100644
--- a/doc/man-sections/client-options.rst
+++ b/doc/man-sections/client-options.rst
@@ -625,9 +625,8 @@
remote.
The probe carries the same control-channel wrapping as a normal
- connection (``--tls-auth`` or ``--tls-crypt``, when configured). With
- ``--tls-crypt-v2`` the remotes are left in their configured order,
- because the server cannot unwrap an out-of-band probe yet.
+ connection (``--tls-auth``, ``--tls-crypt`` or ``--tls-crypt-v2``,
+ when configured).
Only UDP remotes are probed, and only when there are at least two
remotes; remotes reached through a SOCKS proxy are not probed. The
diff --git a/src/openvpn/oob_client.c b/src/openvpn/oob_client.c
index 70c9675..35c71e3 100644
--- a/src/openvpn/oob_client.c
+++ b/src/openvpn/oob_client.c
@@ -73,6 +73,7 @@
/* What each probe is built from; only the request_id differs. */
struct tls_auth_standalone *tas;
struct session_id *client_sid;
+ int opcode;
struct oob_probe_request req;
#ifdef TARGET_ANDROID
bool fd_protected[PROBE_AF_COUNT]; /* VPNService protect(), once per
socket */
@@ -90,22 +91,11 @@
/* Build the standalone wrapping context the probe is sent with, mirroring the
* one the server answers it with, keyed like ce, the entry every other probed
* remote was checked against; without tls-auth/tls-crypt it stays in
- * TLS_WRAP_NONE and the probe goes out in plaintext. Returns NULL (and logs)
- * for tls-crypt-v2, which the probe cannot carry yet. */
+ * TLS_WRAP_NONE and the probe goes out in plaintext. */
static struct tls_auth_standalone *
oob_probe_init_tls_auth_standalone(struct context *c, const struct
connection_entry *ce,
struct gc_arena *gc)
{
- /* tls-crypt-v2 wraps with a per-client key the server only learns from the
- * wrapped client key (WKc) carried in the TLS handshake. An out-of-band
- * probe carries no WKc, so the server cannot unwrap it; skip probing
rather
- * than send something unverifiable. */
- if (ce->tls_crypt_v2_file)
- {
- msg(D_LOW, "server-probe: not supported with tls-crypt-v2; using
configured order");
- return NULL;
- }
-
/* options.ce is not mapped yet; options_postprocess_mutate_ce() has
already
* copied any global key into ce. Loaded again per-connection later. */
do_init_tls_wrap_key(c, ce);
@@ -116,6 +106,14 @@
to.replay_window = c->options.replay_window;
to.replay_time = c->options.replay_time;
+ /* Attach our WKc so tls_wrap_control() appends it. Only a client has one;
+ * a server config's tls-crypt-v2 key leaves the probe in TLS_WRAP_NONE, so
+ * it must not be sent as P_CONTROL_OOB_WKC_V1. */
+ if (ce->tls_crypt_v2_file && c->options.tls_client)
+ {
+ to.tls_wrap.tls_crypt_v2_wkc = &c->c1.ks.tls_crypt_v2_wkc;
+ }
+
struct tls_auth_standalone *tas = tls_auth_standalone_init(&to, gc);
tls_init_control_channel_frame_parameters(&tas->frame, ce->tls_mtu);
@@ -134,6 +132,8 @@
tls_auth_standalone_free(tas);
free_key_ctx_bi(&c->c1.ks.tls_wrap_key);
CLEAR(c->c1.ks.tls_wrap_key);
+ buf_clear(&c->c1.ks.tls_crypt_v2_wkc);
+ free_buf(&c->c1.ks.tls_crypt_v2_wkc);
/* the raw key bytes too: do_init_crypto_tls_c1() may never load a key over
* them, so they would otherwise stay resident for the process lifetime */
secure_memzero(&c->c1.ks.original_wrap_keydata,
sizeof(c->c1.ks.original_wrap_keydata));
@@ -153,7 +153,7 @@
return false;
}
*probe = tls_wrap_oob_standalone(&pc->tas->tls_wrap, pc->tas,
pc->client_sid, &payload,
- P_CONTROL_OOB_V1);
+ pc->opcode);
return BLEN(probe) > 0;
}
@@ -693,14 +693,8 @@
}
/* Wrapping context for the probe (tls-auth/tls-crypt, or plaintext if
- * neither). NULL means this configuration cannot be probed; keep the
- * configured order. */
+ * neither). */
struct tls_auth_standalone *tas = oob_probe_init_tls_auth_standalone(c,
tmpl, &gc);
- if (!tas)
- {
- gc_free(&gc);
- return;
- }
struct probe_ctx pc = { .sd = { SOCKET_UNDEFINED, SOCKET_UNDEFINED } };
struct oob_probe_target *targets = gc_malloc(sizeof(*targets) * l->len,
true, &gc);
@@ -709,18 +703,24 @@
/* Every probe is a single probe request TLV, wrapped (or sent in
* plaintext) like any other control packet, with the client session id as
* the sender session id. Each transmission is built on its own, as each
- * carries its own request_id. */
+ * carries its own request_id. With tls-crypt-v2 the probe must carry the
+ * wrapped client key so the server can recover the per-client key; that is
+ * a P_CONTROL_OOB_WKC_V1 message. Otherwise (tls-crypt v1, tls-auth, or
+ * plaintext) it is a plain P_CONTROL_OOB_V1. */
+ const bool is_v2 = (tas->tls_wrap.tls_crypt_v2_wkc != NULL);
pc.tas = tas;
pc.client_sid = &client_sid;
+ pc.opcode = is_v2 ? P_CONTROL_OOB_WKC_V1 : P_CONTROL_OOB_V1;
pc.id_base = (uint32_t)get_random();
pc.req = (struct oob_probe_request){
.timestamp = (uint64_t)now,
.flags = 0,
};
- const char *wrap_name = (tas->tls_wrap.mode == TLS_WRAP_CRYPT) ?
"tls-crypt"
- : (tas->tls_wrap.mode == TLS_WRAP_AUTH) ?
"tls-auth"
- : "none
(plaintext)";
+ const char *wrap_name = is_v2 ?
"tls-crypt-v2"
+ : (tas->tls_wrap.mode == TLS_WRAP_CRYPT) ?
"tls-crypt"
+ : (tas->tls_wrap.mode == TLS_WRAP_AUTH) ?
"tls-auth"
+ : "none
(plaintext)";
msg(D_LOW, "server-probe: probing %d remote(s) with a %d ms window,
control-channel wrapping: %s",
l->len, OOB_PROBE_WINDOW_MS, wrap_name);
--
To view, visit http://gerrit.openvpn.net/c/openvpn/+/1759?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: I5cc100dd7dc810d7d1e6f29bb57584905fbcf4a0
Gerrit-Change-Number: 1759
Gerrit-PatchSet: 29
Gerrit-Owner: stipa <[email protected]>
Gerrit-Reviewer: plaisthos <[email protected]>
Gerrit-Reviewer: ralf_lici <[email protected]>
Gerrit-CC: openvpn-devel <[email protected]>
Gerrit-Attention: ralf_lici <[email protected]>
Gerrit-Attention: stipa <[email protected]>
Gerrit-Attention: plaisthos <[email protected]>
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel