Re: [Openvpn-devel] [PATCH v4 4/7] Rewrite auth-token-gen to be based on HMAC based tokens

2019-06-25 Thread David Sommerseth
On 13/06/2019 15:48, Arne Schwabe wrote:
> The previous auth-token implementation had a serious problem, especially when
> paired with an unpatched OpenVPN client that keeps trying the auth-token
> (commit e61b401a).
> 
> The auth-token-gen implementation forgot the auth-token on reconnect, this
> lead to reconnect with auth-token never working.
> 
> This new implementation implements the auth-token in a stateles variant. By
> using HMAC to sign the auth-token the server can verify if a token has been
> authenticated and by checking the embedded timestamp in the token it can
> also verify that the auth-token is still valid.
> 
> Using the new config directive auth-gen-token-secret instead of
> extending auth-gen-token (--auth-gen-token [lifetime] [secret-key]) was
> chosen to allow inlinening the secret key.
> 
> Patch V2: cleaned up code, use refactored read_pem_key_file function
> Patch V3: clarify some design decision in the commit message
> Patch V4: Use ephermal_generate_key
> ---
>  doc/openvpn.8|  25 
>  src/openvpn/Makefile.am  |   1 +
>  src/openvpn/auth_token.c | 272 +++
>  src/openvpn/auth_token.h | 116 +
>  src/openvpn/init.c   |  30 -
>  src/openvpn/openvpn.h|   1 +
>  src/openvpn/options.c|  22 +++-
>  src/openvpn/options.h|   4 +
>  src/openvpn/push.c   |  70 --
>  src/openvpn/push.h   |   8 ++
>  src/openvpn/ssl.c|   7 +-
>  src/openvpn/ssl_common.h |  36 --
>  src/openvpn/ssl_verify.c | 182 --
>  13 files changed, 639 insertions(+), 135 deletions(-)
>  create mode 100644 src/openvpn/auth_token.c
>  create mode 100644 src/openvpn/auth_token.h
> 

Not as heavy tested as in last round, but changes has been applied as 
indicated.  Thank you!  Unfortunately, some compiler warnings are appearing:


auth_token.c: In function ‘generate_auth_token’:
auth_token.c:115:9: warning: dereferencing type-punned pointer will break 
strict-aliasing rules [-Wstrict-aliasing]
 initial_timestamp = *((uint64_t *)(old_tstamp_decode));
 ^
auth_token.c: In function ‘verify_auth_token’:
auth_token.c:233:9: warning: format ‘%lld’ expects argument of type ‘long long 
int’, but argument 3 has type ‘uint64_t’ [-Wformat=]
 msg(M_WARN, "Initial timestamp (%lld) in token from client earlier 
than "
 ^
auth_token.c:233:9: warning: format ‘%lld’ expects argument of type ‘long long 
int’, but argument 4 has type ‘uint64_t’ [-Wformat=]



The first one (dereferencing type-punned pointer) seems to only show up with
gcc-4.8.5 and 6.3.1.  Below are warnings reported by both gcc-7.3.1 and 8.3.1,
which are also a bit more verbose, with a few additional twists.


auth_token.c: In function ‘verify_auth_token’:
auth_token.c:233:21: warning: format ‘%lld’ expects argument of type ‘long long 
int’, but argument 3 has type ‘uint64_t’ {aka ‘long unsigned int’} [-Wformat=]
 msg(M_WARN, "Initial timestamp (%lld) in token from client earlier 
than "
 
^
auth_token.c:235:13:
 timestamp_initial, timestamp);
 ~
error.h:151:67: note: in definition of macro ‘msg’
 #define msg(flags, ...) do { if (msg_test(flags)) {x_msg((flags), 
__VA_ARGS__);} EXIT_FATAL(flags); } while (false)
   ^~~
auth_token.c:233:44: note: format string is defined here
 msg(M_WARN, "Initial timestamp (%lld) in token from client earlier 
than "
 ~~~^
 %ld
In file included from buffer.h:28,
 from auth_token.c:10:
auth_token.c:233:21: warning: format ‘%lld’ expects argument of type ‘long long 
int’, but argument 4 has type ‘uint64_t’ {aka ‘long unsigned int’} [-Wformat=]
 msg(M_WARN, "Initial timestamp (%lld) in token from client earlier 
than "
 
^
auth_token.c:235:32:
 timestamp_initial, timestamp);
~
error.h:151:67: note: in definition of macro ‘msg’
 #define msg(flags, ...) do { if (msg_test(flags)) {x_msg((flags), 
__VA_ARGS__);} EXIT_FATAL(flags); } while (false)
   ^~~
auth_token.c:234:36: note: format string is defined here
 "current timestamp (%lld). Broken/unsynchronised clock?",
 ~~~^
 %ld


Other than these issues, things looks good and would normally get an ACK.


-- 
kind 

[Openvpn-devel] [PATCH v4 4/7] Rewrite auth-token-gen to be based on HMAC based tokens

2019-06-13 Thread Arne Schwabe
The previous auth-token implementation had a serious problem, especially when
paired with an unpatched OpenVPN client that keeps trying the auth-token
(commit e61b401a).

The auth-token-gen implementation forgot the auth-token on reconnect, this
lead to reconnect with auth-token never working.

This new implementation implements the auth-token in a stateles variant. By
using HMAC to sign the auth-token the server can verify if a token has been
authenticated and by checking the embedded timestamp in the token it can
also verify that the auth-token is still valid.

Using the new config directive auth-gen-token-secret instead of
extending auth-gen-token (--auth-gen-token [lifetime] [secret-key]) was
chosen to allow inlinening the secret key.

Patch V2: cleaned up code, use refactored read_pem_key_file function
Patch V3: clarify some design decision in the commit message
Patch V4: Use ephermal_generate_key
---
 doc/openvpn.8|  25 
 src/openvpn/Makefile.am  |   1 +
 src/openvpn/auth_token.c | 272 +++
 src/openvpn/auth_token.h | 116 +
 src/openvpn/init.c   |  30 -
 src/openvpn/openvpn.h|   1 +
 src/openvpn/options.c|  22 +++-
 src/openvpn/options.h|   4 +
 src/openvpn/push.c   |  70 --
 src/openvpn/push.h   |   8 ++
 src/openvpn/ssl.c|   7 +-
 src/openvpn/ssl_common.h |  36 --
 src/openvpn/ssl_verify.c | 182 --
 13 files changed, 639 insertions(+), 135 deletions(-)
 create mode 100644 src/openvpn/auth_token.c
 create mode 100644 src/openvpn/auth_token.h

diff --git a/doc/openvpn.8 b/doc/openvpn.8
index 25195fd4..cb63e218 100644
--- a/doc/openvpn.8
+++ b/doc/openvpn.8
@@ -3720,6 +3720,9 @@ the token authentication internally and it will NOT do any
 additional authentications against configured external
 user/password authentication mechanisms.
 
+The tokens implemented by this mechanism include a initial timestamp
+and a renew timestamp and are secured by HMAC.
+
 The
 .B lifetime
 argument defines how long the generated token is valid.  The
@@ -3730,6 +3733,16 @@ This feature is useful for environments which is 
configured
 to use One Time Passwords (OTP) as part of the user/password
 authentications and that authentication mechanism does not
 implement any auth\-token support.
+.\"*
+.TP
+.B \-\-auth\-gen\-token\-secret [file]
+Specifies a file that hold a secret for the HMAC used in
+.B \-\-auth\-gen\-token
+If not present OpenVPN will generate a random secret on startup. This file
+should be used if auth-token should valid after restarting a server or if
+client should be able to roam between multiple OpenVPN server with their
+auth\-token.
+
 .\"*
 .TP
 .B \-\-opt\-verify
@@ -5769,6 +5782,17 @@ Servers can use
 .B \-\-tls\-crypt\-v2\-verify
 to specify a metadata verification command.
 .\"*
+.TP
+.B \-\-genkey auth\-token [keyfile]
+Generate a new secret that can be used
+with
+.B \-\-auth\-gen\-token\-secret
+
+.B Note:
+this file should be kept secret to the server as anyone
+that access to this file will be to generate auth tokens
+that the OpenVPN server will accept as valid.
+.\"*
 .SS TUN/TAP persistent tunnel config mode:
 Available with Linux 2.4.7+.  These options comprise a standalone mode
 of OpenVPN which can be used to create and delete persistent tunnels.
@@ -6980,6 +7004,7 @@ X509_1_C=KG
 OpenVPN allows including files in the main configuration for the
 .B \-\-ca, \-\-cert, \-\-dh, \-\-extra\-certs, \-\-key, \-\-pkcs12, \-\-secret,
 .B \-\-crl\-verify, \-\-http\-proxy\-user\-pass, \-\-tls\-auth,
+.B \-\-auth\-gen\-token\-secret
 .B \-\-tls\-crypt,
 and
 .B \-\-tls\-crypt-v2
diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 30caa01f..3754fd95 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -39,6 +39,7 @@ sbin_PROGRAMS = openvpn
 
 openvpn_SOURCES = \
argv.c argv.h \
+   auth_token.c auth_token.h \
base64.c base64.h \
basic.h \
buffer.c buffer.h \
diff --git a/src/openvpn/auth_token.c b/src/openvpn/auth_token.c
new file mode 100644
index ..0c515fce
--- /dev/null
+++ b/src/openvpn/auth_token.c
@@ -0,0 +1,272 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+
+#include "base64.h"
+#include "buffer.h"
+#include "crypto.h"
+#include "openvpn.h"
+#include "ssl_common.h"
+#include "auth_token.h"
+#include "push.h"
+#include "integer.h"
+#include "ssl.h"
+
+const char *auth_token_pem_name = "OpenVPN auth-token server key";
+
+
+/* Size of the data of the token (not b64 encoded and without prefix) */
+#define TOKEN_DATA_LEN (2 * sizeof(int64_t) + 32)
+
+static struct key_type