Skip to contentSkip to conversation

make tls-auth a per-connection-block option

PATCH In review Antonio Quartulli 4 participants 9 messages Jun 2, 2018 – Jun 4, 2018

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 make tls-auth a per-connection-block option

Different VPN servers may use different tls-auth keys. For this reason it is convenient to make tls-auth a per-connection-block option so that the user is allowed to specify one key per remote.

If no tls-auth option is specified in a given connection block, the global one, if any, is used.

Trac: #720

---
 doc/openvpn.8         |  1 +
 src/openvpn/init.c    | 10 +++---
 src/openvpn/options.c | 82 ++++++++++++++++++++++++++++++++++---------
 src/openvpn/options.h |  5 +++
 4 files changed, 77 insertions(+), 21 deletions(-)
doc/openvpn.8 +1 -0
index 4114f408..e7bc3f4f 100644
@@ -372,6 +372,7 @@ block:
 .B remote,
 .B rport,
 .B socks\-proxy,
+.B tls\-auth,
 .B tun\-mtu and
 .B tun\-mtu\-extra.
 
src/openvpn/init.c +6 -4
index 36c1a4c4..1c43c495 100644
@@ -2546,7 +2546,7 @@ do_init_crypto_tls_c1(struct context *c)
         prng_init(options->prng_hash, options->prng_nonce_secret_len);
 
         /* TLS handshake authentication (--tls-auth) */
-        if (options->tls_auth_file)
+        if (options->ce.tls_auth_file)
         {
             /* Initialize key_type for tls-auth with auth only */
             CLEAR(c->c1.ks.tls_auth_key_type);
@@ -2563,8 +2563,10 @@ do_init_crypto_tls_c1(struct context *c)
             }
 
             crypto_read_openvpn_key(&c->c1.ks.tls_auth_key_type,
-                                    &c->c1.ks.tls_wrap_key, options->tls_auth_file,
-                                    options->tls_auth_file_inline, options->key_direction,
+                                    &c->c1.ks.tls_wrap_key,
+                                    options->ce.tls_auth_file,
+                                    options->ce.tls_auth_file_inline,
+                                    options->ce.key_direction,
                                     "Control Channel Authentication", "tls-auth");
         }
 
@@ -2783,7 +2785,7 @@ do_init_crypto_tls(struct context *c, const unsigned int flags)
 #endif
 
     /* TLS handshake authentication (--tls-auth) */
-    if (options->tls_auth_file)
+    if (options->ce.tls_auth_file)
     {
         to.tls_wrap.mode = TLS_WRAP_AUTH;
         to.tls_wrap.opt.key_ctx_bi = c->c1.ks.tls_wrap_key;
src/openvpn/options.c +65 -17

139 lines not on this page · raw message

src/openvpn/options.h +5 -0
index f7d0145a..77c963d2 100644
@@ -130,6 +130,11 @@ struct connection_entry
 #define CE_MAN_QUERY_REMOTE_MASK   (0x07)
 #define CE_MAN_QUERY_REMOTE_SHIFT  (2)
     unsigned int flags;
+
+    /* Shared secret used for TLS control channel authentication */
+    const char *tls_auth_file;
+    const char *tls_auth_file_inline;
+    int key_direction;
 };
 
 struct remote_entry
Signature · 1 line
2.17.1
#1 lore raw

PATCH 2/2 make tls-crypt a per-connection-block option

Similarly to tls-auth, different remotes may use different tls-crypt keys.

Allow the user to define a different key in each connection block.

If no tls-crypt option is specified in a given connection block, the global one, if any, is used.

Trac: #720

---
 doc/openvpn.8         |  1 +
 src/openvpn/init.c    |  7 ++++---
 src/openvpn/options.c | 48 ++++++++++++++++++++++++++++++++++---------
 src/openvpn/options.h |  4 ++++
 4 files changed, 47 insertions(+), 13 deletions(-)
doc/openvpn.8 +1 -0
index e7bc3f4f..ce21518b 100644
@@ -373,6 +373,7 @@ block:
 .B rport,
 .B socks\-proxy,
 .B tls\-auth,
+.B tls\-crypt,
 .B tun\-mtu and
 .B tun\-mtu\-extra.
 
src/openvpn/init.c +4 -3
index 1c43c495..6d5dd9aa 100644
@@ -2571,9 +2571,10 @@ do_init_crypto_tls_c1(struct context *c)
         }
 
         /* TLS handshake encryption+authentication (--tls-crypt) */
-        if (options->tls_crypt_file)
+        if (options->ce.tls_crypt_file)
         {
-            tls_crypt_init_key(&c->c1.ks.tls_wrap_key, options->tls_crypt_file,
+            tls_crypt_init_key(&c->c1.ks.tls_wrap_key,
+                               options->ce.tls_crypt_file,
                                options->tls_crypt_inline, options->tls_server);
         }
 
@@ -2796,7 +2797,7 @@ do_init_crypto_tls(struct context *c, const unsigned int flags)
     }
 
     /* TLS handshake encryption (--tls-crypt) */
-    if (options->tls_crypt_file)
+    if (options->ce.tls_crypt_file)
     {
         to.tls_wrap.mode = TLS_WRAP_CRYPT;
         to.tls_wrap.opt.key_ctx_bi = c->c1.ks.tls_wrap_key;
src/openvpn/options.c +38 -10

93 lines not on this page · raw message

src/openvpn/options.h +4 -0
index 77c963d2..fcde90af 100644
@@ -135,6 +135,10 @@ struct connection_entry
     const char *tls_auth_file;
     const char *tls_auth_file_inline;
     int key_direction;
+
+    /* Shared secret used for TLS control channel authenticated encryption */
+    const char *tls_crypt_file;
+    bool tls_crypt_inline;
 };
 
 struct remote_entry
Signature · 1 line
2.17.1
#2 lore raw
In reply to Antonio Quartulli

Hi,

Quoted 3 lines · Antonio Quartulli

Different VPN servers may use different tls-auth keys. For this reason it is convenient to make tls-auth a per-connection-block option so that the user is allowed to specify one key per remote.

Want! This also helps with tls-auth key rollover. Feature-ACK.

Quoted 18 lines

If no tls-auth option is specified in a given connection block, the global one, if any, is used.

Trac: #720

---
 doc/openvpn.8         |  1 +
 src/openvpn/init.c    | 10 +++---
 src/openvpn/options.c | 82 ++++++++++++++++++++++++++++++++++---------
 src/openvpn/options.h |  5 +++
 4 files changed, 77 insertions(+), 21 deletions(-)
doc/openvpn.8 +0 -0
index 4114f408..e7bc3f4f 100644

doc/openvpn.8 block: · line 377

Quoted 6 lines
doc/openvpn.8 +1 -0
@@ -372,6 +372,7 @@ block:
 .B remote,
 .B rport,
 .B socks\-proxy,
+.B tls\-auth,
 .B tun\-mtu and
 .B tun\-mtu\-extra.

Shouldn't this also include key-direction?

(Didn't really review or test yet, but otherwise looks good at first glance.)

-Steffan

#3 lore raw

Hi,

Quoted 22 lines · Steffan Karger

Hi,

Quoted 3 lines · Antonio Quartulli

Different VPN servers may use different tls-auth keys. For this reason it is convenient to make tls-auth a per-connection-block option so that the user is allowed to specify one key per remote.

Want! This also helps with tls-auth key rollover. Feature-ACK.

Quoted 13 lines

If no tls-auth option is specified in a given connection block, the global one, if any, is used.

Trac: #720

---
 doc/openvpn.8         |  1 +
 src/openvpn/init.c    | 10 +++---
 src/openvpn/options.c | 82 ++++++++++++++++++++++++++++++++++---------
 src/openvpn/options.h |  5 +++
 4 files changed, 77 insertions(+), 21 deletions(-)
Quoted 14 lines

doc/openvpn.8 block: · line 377

Quoted 11 lines
doc/openvpn.8 +1 -0
index 4114f408..e7bc3f4f 100644
@@ -372,6 +372,7 @@ block:
 .B remote,
 .B rport,
 .B socks\-proxy,
+.B tls\-auth,
 .B tun\-mtu and
 .B tun\-mtu\-extra.

Shouldn't this also include key-direction?

good catch!
I added the manpage change at the end and I forgot about key-direction.

Will wait a bit more before sending v2.

Quoted 3 lines

(Didn't really review or test yet, but otherwise looks good at first glance.)

Thanks so far

Cheers,

Signature · 1 line
Antonio Quartulli
#4 lore raw
In reply to Antonio Quartulli

Hi all,

Quoted 10 lines · Antonio Quartulli

Different VPN servers may use different tls-auth keys. For this reason it is convenient to make tls-auth a per-connection-block option so that the user is allowed to specify one key per remote.

If no tls-auth option is specified in a given connection block, the global one, if any, is used.

Trac: #720

as reported by Steffan on IRC, this feature breaks when using "--persist-key".
It happens because, when moving to the next connection block, OpenVPN won't load the new tls-auth key and therefore will trigger an assertion.

After further discussing this issue, it was agreed that we have two main options to tackle this issue:

1) pre-load all the tls-auth keyfiles (like if they were embedded in the config file)
2) make per-connection-block tls-auth keys mutually exclusive with --persist-key

while point 2) would be the easiest option and would require the least amount of code, we believe that 1) is still the best from the user perspective and from the option semantics point of view (as it would not lead to any behaviour change).

Therefore a v2 patch will be sent implementing approach 1).

Cheers,

Signature · 1 line
Antonio Quartulli
#5 lore raw

Hi Antonio,

Quoted 27 lines · Antonio Quartulli

Hi all,

Quoted 10 lines · Antonio Quartulli

Different VPN servers may use different tls-auth keys. For this reason it is convenient to make tls-auth a per-connection-block option so that the user is allowed to specify one key per remote.

If no tls-auth option is specified in a given connection block, the global one, if any, is used.

Trac: #720

as reported by Steffan on IRC, this feature breaks when using "--persist-key".
It happens because, when moving to the next connection block, OpenVPN won't load the new tls-auth key and therefore will trigger an assertion.

After further discussing this issue, it was agreed that we have two main options to tackle this issue:

1) pre-load all the tls-auth keyfiles (like if they were embedded in the config file)
2) make per-connection-block tls-auth keys mutually exclusive with --persist-key

Quoted 8 lines

while point 2) would be the easiest option and would require the least amount of code, we believe that 1) is still the best from the user perspective and from the option semantics point of view (as it would not lead to any behaviour change).

Therefore a v2 patch will be sent implementing approach 1).

this is a very interesting patch ! And I agree, approach 1) is the way to go, as we've been advising people to use "persist-key" for a looong time now.

What's the particular use case for putting tls-auth files in connection blocks?  Does it apply only to tls-auth/tls-crypt files or also the certificate/private keys?  I could see a use case for that as well...

JM2CW,

JJK

#6 lore raw

Hi,

Quoted 2 lines · Jan Just Keijser

What's the particular use case for putting tls-auth files in connection blocks?

"I have one existing server that is not using tls-auth yet, and a new one that has tls-auth, and I want both in the same config file"

Plus, what Steffan mentioned: tls-auth rollover

Quoted 2 lines

Does it apply only to tls-auth/tls-crypt files or also the certificate/private keys?  I could see a use case for that as well...

Right now, only tls-auth/tls-crypt, but this is the same question I asked on IRC yesterday :-)

The "traditional" use case ("my key/cert is my identity") would see "a single identity for all remotes", but indeed, upgrading to a new server with a new CA (--ca -> <connection>) and newly distributed identities might also be an interesting use case. For @work, I've decided to tackle this part with "just distribute two .ovpn files", but it's worth thinking through the idea.

gert

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...
#7 lore raw

Hi,

Gert has been faster to reply :-)

Quoted 9 lines · Gert Doering

Hi,

Quoted 2 lines · Jan Just Keijser

What's the particular use case for putting tls-auth files in connection blocks?

"I have one existing server that is not using tls-auth yet, and a new one that has tls-auth, and I want both in the same config file"

Exactly. Or even extend the same reasoning to tls-crypt:
"one server was migrated to tls-crypt and one is still on tls-auth, and both have to be in the same config file".

Quoted 9 lines

Plus, what Steffan mentioned: tls-auth rollover

Quoted 2 lines

Does it apply only to tls-auth/tls-crypt files or also the certificate/private keys?  I could see a use case for that as well...

Right now, only tls-auth/tls-crypt, but this is the same question I asked on IRC yesterday :-)

Quoted 7 lines

The "traditional" use case ("my key/cert is my identity") would see "a single identity for all remotes", but indeed, upgrading to a new server with a new CA (--ca -> <connection>) and newly distributed identities might also be an interesting use case. For @work, I've decided to tackle this part with "just distribute two .ovpn files", but it's worth thinking through the idea.

Once the issue with "--persist-key" has been fixed (will be in v2 of this patchset) I think it should be easy[tm] to also implement key/cert/ca per connection block.

Cheers,

Signature · 1 line
Antonio Quartulli
#8 lore raw
In reply to Gert Doering

Hi,

Quoted 8 lines · Gert Doering
Quoted 2 lines · Jan Just Keijser

What's the particular use case for putting tls-auth files in connection blocks?

"I have one existing server that is not using tls-auth yet, and a new one that has tls-auth, and I want both in the same config file"

Plus, what Steffan mentioned: tls-auth rollover

hmmm, of course, some people even asked me what the best way to do tls-auth rollover is...

I could also see a use case where you have a single config with "proto udp" and "proto tcp" , where the "proto udp" block has a tls-auth key but the "proto tcp" does not  -   the use case for "tls-auth" is mostly UDP anyways, as TCP connections are not so easy to protect against DoS attacks.  I assume that will also be possible?

JJK