[Openvpn-devel,v1] tls_crypt: Wipe the tls-crypt-v2 client key copies

Message ID 20261102101437.1209-1-gert@greenie.muc.de
State New
Headers
Series [Openvpn-devel,v1] tls_crypt: Wipe the tls-crypt-v2 client key copies |

Commit Message

Gert Doering Nov. 2, 2026, 10:14 a.m. UTC
  From: Hansaem Wi <hansaemw@gmail.com>

tls_crypt_v2_init_client_key() reads the client key into a struct key2
on the stack, copies it to *original_key and returns without clearing
it, so every client start leaves the tls-crypt-v2 client key on the
stack. crypto_read_openvpn_key() does the same copy for tls-auth and
tls-crypt keys and clears its struct key2 afterwards; do the same here.

The --genkey tls-crypt-v2-client sanity check in
tls_crypt_v2_write_client_key_file() has two more copies:
- keydata, the struct key2 that tls_crypt_v2_init_client_key() fills;
  clear it after use.
- check_wrapped_client_key, the decoded key file buffer: the client key
  is still in front of the wrapped key when it is freed. Clear it with
  buf_clear() before free_buf(), as do_close_free_key_schedule() does
  for the client's tls_crypt_v2_wkc.

Assisted-by: Claude Code:claude-opus-5-5
Change-Id: I8e02b4cf39cc431f1f2c058db95997c8907557c0
Signed-off-by: Hansaem Wi <hansaemw@gmail.com>
Acked-by: Steffan Karger <steffan@karger.me>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/2079
---

This change was reviewed on Gerrit and approved by at least one
developer. I request to merge it to master.

Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/2079
This mail reflects revision 1 of this Change.

Acked-by according to Gerrit (reflected above):
Steffan Karger <steffan@karger.me>
  

Patch

diff --git a/src/openvpn/tls_crypt.c b/src/openvpn/tls_crypt.c
index 23c7975..ee4acdf 100644
--- a/src/openvpn/tls_crypt.c
+++ b/src/openvpn/tls_crypt.c
@@ -331,6 +331,7 @@ 
 
     tls_crypt_v2_load_client_key(key, &key2, false);
     *original_key = key2;
+    secure_memzero(&key2, sizeof(key2));
 
     *wkc_buf = client_key;
 }
@@ -783,6 +784,7 @@ 
     tls_crypt_v2_init_client_key(&check_client_key, &keydata, &check_wrapped_client_key, client_file,
                                  client_inline);
     free_key_ctx_bi(&check_client_key);
+    secure_memzero(&keydata, sizeof(keydata));
 
     /* Sanity check: unwrap and load client key (as "server") */
     struct buffer check_metadata = alloc_buf_gc(TLS_CRYPT_V2_MAX_METADATA_LEN, &gc);
@@ -793,6 +795,7 @@ 
     ASSERT(tls_crypt_v2_unwrap_client_key(&check_client_key2, &check_metadata,
                                           check_wrapped_client_key, &server_key));
     secure_memzero(&check_client_key2, sizeof(check_client_key2));
+    buf_clear(&check_wrapped_client_key);
     free_buf(&check_wrapped_client_key);
 
 cleanup: