Re: [Openvpn-devel] [PATCH] Fix delcarion of pubkeys in test_provider.c in MSVC builds

2022-08-25 Thread Selva Nair
On Thu, Aug 25, 2022 at 4:37 PM Gert Doering  wrote:

> Hi,
>
> On Wed, Aug 24, 2022 at 06:57:18PM +0200, Arne Schwabe wrote:
> >   Error: test_provider.c(74): error C2099: initializer is not a constant
> >
> > Fix this issue by making the const char* to const char[]. This is
> probably
> > of one the weird array decay corner cases
>
> Out of curiosity - does the error go away if you just remove all these
> "const" from the declaration?  Making this just a "static char *"?
>

The  const after * in the original was to make the pointer a compile-time
constant and usable as an initializer. Else even gcc and clang will error
out. The const before * indicating the value is a constant could be
removed, but the value is in fact a constant string literal, so why do
so

Anyway, for some reason MSVC doesn't seem to accept any form other than
what Arne proposed. Unless we define pubkeys[] using the three string
literals directly and eliminate those intermediate vars (pubkey1, 2, 3).
.
Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH applied] Re: Allow a few levels of recursion in virtual_output_callback()

2022-08-22 Thread Selva Nair
In case this request was lost, here goes again. Can we have this
cherry-picked into 2.5 before the next release?

Selva

On Thu, Aug 11, 2022 at 4:03 PM Selva Nair  wrote:

> Hi,
>
> On Tue, Aug 2, 2022 at 8:02 AM Gert Doering  wrote:
>
>> Acked-by: Gert Doering 
>>
>> I cannot test this (beyond "compile", but that is trivial) but the
>> description in
>>
>>
>> https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg24738.html
>>
>> makes sense, so allowing "a limited amount" of recursion plus actually
>> logging when this is hit should make management more robust against
>> overlapping timing issues aka "race conditions".
>>
>> Your patch has been applied to the master branch.
>>
>
> Can we also apply this to 2.5? I see this trigerred easily with the new
> persistent connection / PLAP support. I haven't figured the exact reason
> but hitting reconnect or disconnect at certain instances triggers this --
> like when the connection is almost complete and the daemon is doing
> slow-ish netsh commands. The same code-path is not traversed when
> interactive service is in use and it seems hitting the "race condition" is
> much harder in that case.
>
> Otherwise we have to limit these new GUI features to 2.6 which  would
> require a new branch in the GUI and some changes to the build process.
>
> In some sense this is a "bug fix" though the fix itself is a band-aid as
> opposed to implementing a command queue to save these write actions instead
> of dropping them.
>
> Selva
>
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v102 3/7] dco-win: implement ovpn-dco support in P2P Windows code path

2022-08-21 Thread Selva Nair
Hi,

Did a quick test on Windows 10 and appears to work as expected. Some minor
things:

(i) I had persist-tun which caused a fatal error that required opening the
log file to find what's wrong and then fix the config file -- unfortunately
the GUI status window cannot display such early errors. Isn't a warning
that persist-tun is not supported enough?

(ii) windows-driver ovpn-dco   (without the trailing -win) would be better?
"windows" is already there in the option name.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH applied] Re: Allow a few levels of recursion in virtual_output_callback()

2022-08-11 Thread Selva Nair
Hi,

On Tue, Aug 2, 2022 at 8:02 AM Gert Doering  wrote:

> Acked-by: Gert Doering 
>
> I cannot test this (beyond "compile", but that is trivial) but the
> description in
>
>
> https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg24738.html
>
> makes sense, so allowing "a limited amount" of recursion plus actually
> logging when this is hit should make management more robust against
> overlapping timing issues aka "race conditions".
>
> Your patch has been applied to the master branch.
>

Can we also apply this to 2.5? I see this trigerred easily with the new
persistent connection / PLAP support. I haven't figured the exact reason
but hitting reconnect or disconnect at certain instances triggers this --
like when the connection is almost complete and the daemon is doing
slow-ish netsh commands. The same code-path is not traversed when
interactive service is in use and it seems hitting the "race condition" is
much harder in that case.

Otherwise we have to limit these new GUI features to 2.6 which  would
require a new branch in the GUI and some changes to the build process.

In some sense this is a "bug fix" though the fix itself is a band-aid as
opposed to implementing a command queue to save these write actions instead
of dropping them.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] openvpnmsica: remove OpenVPNService state check code

2022-08-04 Thread Selva Nair
Hi,

On Thu, Jul 28, 2022 at 7:19 AM Lev Stipakov  wrote:

> From: Lev Stipakov 
>
> This code reads the state of OpenVPNService,
> such as startup mode and running, and sets MSI
> property value. If that property is set, installer
> selects OpenVPNService as a feature to be installed.
>
> This has been superseded by change in installer:
>
>   https://github.com/OpenVPN/openvpn-build/pull/261
>
> which, in addition to checking the state of OpenVPNService,
> applies that state to the newly installed service.
>
>   - by default, OpenVPNService feature is now checked
> and service is installed
>
>   - in clean installation, service startup mode is set to "manual"
> and service is not started
>
>   - in upgrade, installer preserves the service state, such
> as startup mode and started/stopped
>
> With all those changes to installer, we don't need this code
> in openvpnmsica.
>
> Signed-off-by: Lev Stipakov 
> ---
>  src/openvpnmsica/openvpnmsica.c | 115 
>  1 file changed, 115 deletions(-)
>

With PR261 in openvpn-build merged, this is now ready.

Acked-by: Selva Nair 
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 2/2] Allow a few levels of recursion in virtual_output_callback()

2022-07-27 Thread selva . nair
From: Selva Nair 

Without this, replies to commands from the management client
are sometimes lost if the server is writing when a command
comes in and leads to a recursive call to this function.

For some reason I've not been able to trigger this on Linux,
but it does sometimes happen on Windows during intense write
activity by openvpn.exe sending log lines to the management
client.

Signed-off-by: Selva Nair 
---
 src/openvpn/manage.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c
index 27aa49a8..5670e594 100644
--- a/src/openvpn/manage.c
+++ b/src/openvpn/manage.c
@@ -312,8 +312,7 @@ virtual_output_callback_func(void *arg, const unsigned int 
flags, const char *st
 
 #define AF_DID_PUSH  (1<<0)
 #define AF_DID_RESET (1<<1)
-
-if (!recursive_level) /* don't allow recursion */
+if (recursive_level < 5) /* limit recursion */
 {
 struct gc_arena gc = gc_new();
 struct log_entry e;
@@ -380,6 +379,12 @@ virtual_output_callback_func(void *arg, const unsigned int 
flags, const char *st
 
 --recursive_level;
 }
+else
+{
+/* cannot use msg here */
+printf("virtual_output: message to management interface "
+   "dropped due to recursion: <%s>\n", str);
+}
 }
 
 /*
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 1/2] Do not skip ERROR:/SUCCESS: response from management interface

2022-07-27 Thread selva . nair
From: Selva Nair 

Generally we expect a response of SUCCESS: or ERROR: to every
command sent to the management interface. But, while in
the management-hold state, sending "signal foo" returns only
the following reply (with foo = SIGHUP, SIGUSR1 etc.):

>HOLD:Waiting for hold release:0

Fix by always responding

ERROR: signal 'foo' is currently ignored"
followed by the above line.

Though this is seldom seen in practice[*], such violation of the
protocol could stall clients like the GUI. So fix it.

[*] One way this happens is with SIGHUP sent before the daemon
is on hold state which it enters before the SIGHUP is received.

Signed-off-by: Selva Nair 
---
 src/openvpn/manage.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c
index 5d58c662..27aa49a8 100644
--- a/src/openvpn/manage.c
+++ b/src/openvpn/manage.c
@@ -426,14 +426,11 @@ man_signal(struct management *man, const char *name)
 }
 else
 {
+msg(M_CLIENT, "ERROR: signal '%s' is currently ignored", name);
 if (man->persist.special_state_msg)
 {
 msg(M_CLIENT, "%s", man->persist.special_state_msg);
 }
-else
-{
-msg(M_CLIENT, "ERROR: signal '%s' is currently ignored", name);
-}
 }
 }
 else
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH v2] xkey_provider: fix building with --disable-management

2022-07-27 Thread selva . nair
From: Selva Nair 

v2: also fix building test_provider
 - ifdefs in test_provider.c
 - include integer.h for min_int as manage.h
   may not always pull it in

Too many ifdefs, unfortunately..

Signed-off-by: Selva Nair 
---
 src/openvpn/xkey_helper.c| 4 
 tests/unit_tests/openvpn/test_provider.c | 7 +++
 2 files changed, 11 insertions(+)

diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c
index 81dd71dc..27e87d79 100644
--- a/src/openvpn/xkey_helper.c
+++ b/src/openvpn/xkey_helper.c
@@ -85,6 +85,7 @@ xkey_digest(const unsigned char *src, size_t srclen, unsigned 
char *buf,
 return 1;
 }
 
+#ifdef ENABLE_MANAGEMENT
 /**
  * Load external key for signing via management interface.
  * The public key must be passed in by the caller as we may not
@@ -107,6 +108,7 @@ xkey_load_management_key(OSSL_LIB_CTX *libctx, EVP_PKEY 
*pubkey)
 
 return xkey_load_generic_key(libctx, dummy, pubkey, sign_op, NULL);
 }
+#endif
 
 /**
  * Load a generic key into the xkey provider.
@@ -147,6 +149,7 @@ xkey_load_generic_key(OSSL_LIB_CTX *libctx, void *handle, 
EVP_PKEY *pubkey,
 return pkey;
 }
 
+#ifdef ENABLE_MANAGEMENT
 /**
  * Signature callback for xkey_provider with management-external-key
  *
@@ -277,6 +280,7 @@ xkey_management_sign(void *unused, unsigned char *sig, 
size_t *siglen,
 
 return (*siglen > 0);
 }
+#endif /* ENABLE MANAGEMENT */
 
 /**
  * Add PKCS1 DigestInfo to tbs and return the result in *enc.
diff --git a/tests/unit_tests/openvpn/test_provider.c 
b/tests/unit_tests/openvpn/test_provider.c
index 47e7e395..d146af62 100644
--- a/tests/unit_tests/openvpn/test_provider.c
+++ b/tests/unit_tests/openvpn/test_provider.c
@@ -30,6 +30,7 @@
 
 #include "syshead.h"
 #include "manage.h"
+#include "integer.h"
 #include "xkey_common.h"
 
 #ifdef HAVE_XKEY_PROVIDER
@@ -127,7 +128,9 @@ init_test()
 /* set default propq matching what we use in ssl_openssl.c */
 EVP_set_default_properties(NULL, "?provider!=ovpn.xkey");
 
+#ifdef ENABLE_MANAGEMENT
 management = test_calloc(sizeof(*management), 1);
+#endif
 }
 
 static void
@@ -272,6 +275,7 @@ done:
 return sig;
 }
 
+#ifdef ENABLE_MANAGEMENT
 /* Check loading of management external key and have sign callback exercised
  * for RSA and EC keys with and without digest support in management client.
  * Sha256 digest used for both cases with pss padding for RSA.
@@ -310,6 +314,7 @@ again:
 EVP_PKEY_free(privkey);
 }
 }
+#endif
 
 /* helpers for testing generic key load and sign */
 static int xkey_free_called;
@@ -409,7 +414,9 @@ main(void)
 
 const struct CMUnitTest tests[] = {
 cmocka_unit_test(xkey_provider_test_fetch),
+#ifdef ENABLE_MANAGEMENT
 cmocka_unit_test(xkey_provider_test_mgmt_sign_cb),
+#endif
 cmocka_unit_test(xkey_provider_test_generic_sign_cb),
 };
 
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] xkey_provider: fix building with --disable-management

2022-07-26 Thread selva . nair
From: Selva Nair 

Signed-off-by: Selva Nair 
---
 src/openvpn/xkey_helper.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c
index 81dd71dc..27e87d79 100644
--- a/src/openvpn/xkey_helper.c
+++ b/src/openvpn/xkey_helper.c
@@ -85,6 +85,7 @@ xkey_digest(const unsigned char *src, size_t srclen, unsigned 
char *buf,
 return 1;
 }
 
+#ifdef ENABLE_MANAGEMENT
 /**
  * Load external key for signing via management interface.
  * The public key must be passed in by the caller as we may not
@@ -107,6 +108,7 @@ xkey_load_management_key(OSSL_LIB_CTX *libctx, EVP_PKEY 
*pubkey)
 
 return xkey_load_generic_key(libctx, dummy, pubkey, sign_op, NULL);
 }
+#endif
 
 /**
  * Load a generic key into the xkey provider.
@@ -147,6 +149,7 @@ xkey_load_generic_key(OSSL_LIB_CTX *libctx, void *handle, 
EVP_PKEY *pubkey,
 return pkey;
 }
 
+#ifdef ENABLE_MANAGEMENT
 /**
  * Signature callback for xkey_provider with management-external-key
  *
@@ -277,6 +280,7 @@ xkey_management_sign(void *unused, unsigned char *sig, 
size_t *siglen,
 
 return (*siglen > 0);
 }
+#endif /* ENABLE MANAGEMENT */
 
 /**
  * Add PKCS1 DigestInfo to tbs and return the result in *enc.
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] OpenSSL 3.0 builds with --disable-management

2022-07-26 Thread Selva Nair
Hi,

On Tue, Jul 26, 2022 at 2:59 AM Gert Doering  wrote:

>
> I'm just relaying what buildbot found, not suggesting a particular fix
> - not very familiar with these new code paths (do we need xkey at all
> if management is disabled?).
>

xkey handles all external keys including pkcs11 and cryptoapicert, so we
need it even when management is disabled.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] Response from management i/f lost in some cases.

2022-07-25 Thread Selva Nair
Hi,

Generally we expect a response of "SUCCESS: " or "ERROR: ..." to every
command sent to the management interface (in mult-line cases, a terminating
line with "END" too). I've noticed a couple of situations where this is
either missing or gets lost.

(i) While in the hold state, sending "signal SIGHUP" returns only the
following reply:
>HOLD:Waiting for hold release:0
instead of "ERROR: signals are currently disabled", followed by the above
line. (management signals are disabled when on hold).

(ii) The second case is somewhat complex -- at times the daemon does not
send back any response. I've seen this happen only if a command is sent by
the management client when the demon is busy sending LOG messages -- for
example, the user wants to restart and we send "signal SIGHUP" -- if this
gets no response we stall in the GUI waiting for the reply.

I think this is what's happening:  M_CLIENT messages are dropped by
virtual_output_callback() when it gets called recursively. When the daemon
is outputting, say, log lines to the client the above function gets called,
it then calls management_io() to send the message out. But, in
management_io() we process both reads and writes and if a read comes in at
that time, we process it synchronously, generate the response with
flag=M_CLIENT, end up in recursing into virtual_output_callback(). The
response gets dropped there because recursive_level > 0 (recursion not
allowed).

As one cannot control when a user may hit reconnect, this needs to be
fixed.

Would it be okay to allow a few levels of recursion in
virtual_output_callback? One seldom sends more than a couple of commands in
a succession especially when not prompted by the daemon. Allowing
recursive_level up to 5 (or even 3) would go a long way.

Regards,

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] In x_check_status() read errno early

2022-07-22 Thread selva . nair
From: Selva Nair 

The correct errno can get overwritten by the call to
format_extended_socket_error() which may set errno to EAGAIN
losing the original error and cause to bypass the error reporting
below. Fix by reading the errno of interest at the top of the
function.

Reported by: Gert Doering 
Signed-off-by: Selva Nair 
---
 src/openvpn/error.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/openvpn/error.c b/src/openvpn/error.c
index 49ed1dbc..7cd35b17 100644
--- a/src/openvpn/error.c
+++ b/src/openvpn/error.c
@@ -658,6 +658,9 @@ x_check_status(int status,
 {
 const char *extended_msg = NULL;
 
+bool crt_error = false;
+int my_errno = openvpn_errno_maybe_crt(_error);
+
 msg(x_cs_verbose_level, "%s %s returned %d",
 sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "",
 description,
@@ -688,9 +691,6 @@ x_check_status(int status,
 }
 #endif
 
-bool crt_error = false;
-int my_errno = openvpn_errno_maybe_crt(_error);
-
 if (!ignore_sys_error(my_errno, crt_error))
 {
 if (extended_msg)
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v2] Fix M_ERRNO behavior on Windows

2022-07-22 Thread Selva Nair
On Fri, Jul 22, 2022 at 12:17 PM Gert Doering  wrote:

> Hi,
>
> On Tue, May 03, 2022 at 03:28:40AM +0300, Lev Stipakov wrote:
> > From: Lev Stipakov 
> >
> > We use M_ERRNO flag in logging to display error code
> > and error message. This has been broken on Windows,
> > where we use error code from GetLastError() and
> > error description from strerror(). strerror() expects
> > C runtime error code, which is quite different from
> > last error code from WinAPI call. As a result, we got
> > incorrect error description.
>
> This patch breaks extended socket error reporting.
>
> In the git tree, we have those two right next to each other
>
> commit 54800aa975418fe3570f3206a5f9b277dc59bd47
> Author: Lev Stipakov 
> Date:   Tue May 3 03:28:40 2022 +0300
>
> Fix M_ERRNO behavior on Windows
>
>  -> broken
>
> commit 043c67f36342969cd171d24c70ee6b62ebc95fee
> Author: Gert Doering 
> Date:   Tue Feb 22 15:35:14 2022 +0100
>
> Implement --mtu-disc for IPv6 UDP sockets.
>
>  -> works
>
>
> Testing is easy: point openvpn on a Linux system(!) to an unreachable
> destination (--verb 5 used here, but 3 should be sufficient)).
>
> With 043c67f, this gives
>
> 2022-07-22 18:07:59 us=599924 UDPv6 link remote:
> [AF_INET6]2001:608:2:a::253:1196
> W2022-07-22 18:07:59 us=628976 read UDPv6 [ECONNREFUSED]: Connection
> refused (fd=3,code=111)
> W2022-07-22 18:08:02 us=168862 read UDPv6 [ECONNREFUSED]: Connection
> refused (fd=3,code=111)
> W2022-07-22 18:08:07 us=228896 read UDPv6 [ECONNREFUSED]: Connection
> refused (fd=3,code=111)
>
> with 54800aa9754, this becomes
>
> 2022-07-22 18:14:16 us=271797 UDPv6 link remote:
> [AF_INET6]2001:608:2:a::253:1196
> W^C2022-07-22 18:14:46 us=706438 event_wait : Interrupted system call
> (fd=-1,code=4)
>
> ("nothing nothing nothing ctrl-c")
>

This one is tricky -- though the patch appeared to be a no-op for
non-Windows, in error.c:x_check_status(), it did move down  the line
my_errno = openvpn_errno() and thus potentially lose the original error. At
that time it looked like a good move (pun intended), though. So much for
C99 style..

Especially, before outputting the message we call
format_extended_socket_error() which calls recvmsg() which can
easily return EAGAIN in errno. To top it, EAGAIN is completely ignored by
ignore_sys_error(), so we get nothing printed. I think moving those line
back up to the start of the  function should fix this

Selva


>
> I can see that the patch at least touches code close to it...
>
> +#endif /* EXTENDED_SOCKET_ERROR_CAPABILITY */
>
> ... so it would be nice if someone could have a look what this patch
> is trampling on that it shouldn't...
>
> gert
> --
> "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
> g...@greenie.muc.de
> ___
> Openvpn-devel mailing list
> Openvpn-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/openvpn-devel
>
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] Fix crash in xkey-provider in msvc builds

2022-07-14 Thread Selva Nair
Hi,

Any thoughts on this? Apart from the broken msvc builds that led to this,
looks like the right thing to do, isn't it?

Selva

On Wed, Jul 6, 2022 at 11:52 PM  wrote:

> From: Selva Nair 
>
> The function signature for xkey_load_generic_key had
> function pointers defined as function types that seems
> to work in gcc but not in msvc.
>
> Fix it by changing the function signatures to what was
> intended.
> Also revert part of commit 627d1a3d28638... as that work-
> around should be no longer required.
>
> Reported by: Lev Stipakov https://github.com/lstipakov
>
> Signed-off-by: Selva Nair 
> ---
>  src/openvpn/xkey_common.h | 2 +-
>  src/openvpn/xkey_helper.c | 6 +++---
>  2 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h
> index e0e5ed5b..6d6a1e2c 100644
> --- a/src/openvpn/xkey_common.h
> +++ b/src/openvpn/xkey_common.h
> @@ -152,7 +152,7 @@ xkey_digest(const unsigned char *src, size_t srclen,
> unsigned char *buf,
>   */
>  EVP_PKEY *
>  xkey_load_generic_key(OSSL_LIB_CTX *libctx, void *handle, EVP_PKEY
> *pubkey,
> -  XKEY_EXTERNAL_SIGN_fn sign_op, XKEY_PRIVKEY_FREE_fn
> free_op);
> +  XKEY_EXTERNAL_SIGN_fn *sign_op,
> XKEY_PRIVKEY_FREE_fn *free_op);
>
>  extern OSSL_LIB_CTX *tls_libctx; /* Global */
>
> diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c
> index 14f074ae..73235fd6 100644
> --- a/src/openvpn/xkey_helper.c
> +++ b/src/openvpn/xkey_helper.c
> @@ -115,7 +115,7 @@ xkey_load_management_key(OSSL_LIB_CTX *libctx,
> EVP_PKEY *pubkey)
>   */
>  EVP_PKEY *
>  xkey_load_generic_key(OSSL_LIB_CTX *libctx, void *handle, EVP_PKEY
> *pubkey,
> -  XKEY_EXTERNAL_SIGN_fn sign_op, XKEY_PRIVKEY_FREE_fn
> free_op)
> +  XKEY_EXTERNAL_SIGN_fn *sign_op,
> XKEY_PRIVKEY_FREE_fn *free_op)
>  {
>  EVP_PKEY *pkey = NULL;
>  const char *origin = "external";
> @@ -125,8 +125,8 @@ xkey_load_generic_key(OSSL_LIB_CTX *libctx, void
> *handle, EVP_PKEY *pubkey,
>  {"xkey-origin", OSSL_PARAM_UTF8_STRING, (char *) origin, 0, 0},
>  {"pubkey", OSSL_PARAM_OCTET_STRING, , sizeof(pubkey), 0},
>  {"handle", OSSL_PARAM_OCTET_PTR, , sizeof(handle), 0},
> -{"sign_op", OSSL_PARAM_OCTET_PTR, (void **) _op, sizeof(void
> *), 0},
> -{"free_op", OSSL_PARAM_OCTET_PTR, (void **) _op, sizeof(void
> *), 0},
> +{"sign_op", OSSL_PARAM_OCTET_PTR, (void **) _op,
> sizeof(sign_op), 0},
> +{"free_op", OSSL_PARAM_OCTET_PTR, (void **) _op,
> sizeof(free_op), 0},
>  {NULL, 0, NULL, 0, 0}
>  };
>  msg(M_INFO, "%s: handle = %p sign_op = %p free_op = %p ",
> __FUNCTION__,
> --
> 2.30.2
>
>
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] Fix crash in xkey-provider in msvc builds

2022-07-06 Thread selva . nair
From: Selva Nair 

The function signature for xkey_load_generic_key had
function pointers defined as function types that seems
to work in gcc but not in msvc.

Fix it by changing the function signatures to what was
intended.
Also revert part of commit 627d1a3d28638... as that work-
around should be no longer required.

Reported by: Lev Stipakov https://github.com/lstipakov

Signed-off-by: Selva Nair 
---
 src/openvpn/xkey_common.h | 2 +-
 src/openvpn/xkey_helper.c | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h
index e0e5ed5b..6d6a1e2c 100644
--- a/src/openvpn/xkey_common.h
+++ b/src/openvpn/xkey_common.h
@@ -152,7 +152,7 @@ xkey_digest(const unsigned char *src, size_t srclen, 
unsigned char *buf,
  */
 EVP_PKEY *
 xkey_load_generic_key(OSSL_LIB_CTX *libctx, void *handle, EVP_PKEY *pubkey,
-  XKEY_EXTERNAL_SIGN_fn sign_op, XKEY_PRIVKEY_FREE_fn 
free_op);
+  XKEY_EXTERNAL_SIGN_fn *sign_op, XKEY_PRIVKEY_FREE_fn 
*free_op);
 
 extern OSSL_LIB_CTX *tls_libctx; /* Global */
 
diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c
index 14f074ae..73235fd6 100644
--- a/src/openvpn/xkey_helper.c
+++ b/src/openvpn/xkey_helper.c
@@ -115,7 +115,7 @@ xkey_load_management_key(OSSL_LIB_CTX *libctx, EVP_PKEY 
*pubkey)
  */
 EVP_PKEY *
 xkey_load_generic_key(OSSL_LIB_CTX *libctx, void *handle, EVP_PKEY *pubkey,
-  XKEY_EXTERNAL_SIGN_fn sign_op, XKEY_PRIVKEY_FREE_fn 
free_op)
+  XKEY_EXTERNAL_SIGN_fn *sign_op, XKEY_PRIVKEY_FREE_fn 
*free_op)
 {
 EVP_PKEY *pkey = NULL;
 const char *origin = "external";
@@ -125,8 +125,8 @@ xkey_load_generic_key(OSSL_LIB_CTX *libctx, void *handle, 
EVP_PKEY *pubkey,
 {"xkey-origin", OSSL_PARAM_UTF8_STRING, (char *) origin, 0, 0},
 {"pubkey", OSSL_PARAM_OCTET_STRING, , sizeof(pubkey), 0},
 {"handle", OSSL_PARAM_OCTET_PTR, , sizeof(handle), 0},
-{"sign_op", OSSL_PARAM_OCTET_PTR, (void **) _op, sizeof(void *), 
0},
-{"free_op", OSSL_PARAM_OCTET_PTR, (void **) _op, sizeof(void *), 
0},
+{"sign_op", OSSL_PARAM_OCTET_PTR, (void **) _op, sizeof(sign_op), 
0},
+{"free_op", OSSL_PARAM_OCTET_PTR, (void **) _op, sizeof(free_op), 
0},
 {NULL, 0, NULL, 0, 0}
 };
 msg(M_INFO, "%s: handle = %p sign_op = %p free_op = %p ", __FUNCTION__,
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] Bug in msvc build of master + OpenSSL 3.0.x

2022-07-06 Thread Selva Nair
Hi,

As reported by Lev here:
https://github.com/OpenVPN/openvpn-gui/pull/508#issuecomment-1174057372

I think its due to this in xkey-provider:

typedef void (XKEY_PRIVKEY_FREE_fn)(void *handle);
(and a similar one for SIGN_fn)

EVP_PKEY *
xkey_load_generic_key(OSSL_LIB_CTX *libctx, void *handle, EVP_PKEY *pubkey,
XKEY_EXTERNAL_SIGN_fn sign_op, XKEY_PRIVKEY_FREE_fn free_op)
{
...

...
}

(see xkey_helper. around line:120, and xkey_common.h for declarations).

Note the lack of * before the sign_op and free_op variables in the function
definition and declaration (not shown). The typedefs are without a * as
well, but that is deliberate and intentional.

This is not flagged as a bug by gcc or msvc, and it seems both
automatically assign function pointers to sign_op and free_op as intended.
Problem seems to be that when I take the pointer to sign_op to pass to
OpenSSL, gcc does give a pointer to the function-ptr that we need, but msvc
does something else which later gets dereferenced in the provider.

In fact we had an error from msvc builds about sizeof(sign_op) not legal,
which should have been a red-flag. But we worked around it in
commit 627d1a3d28 by replacing it with sizeof(void *) --- typical
cast-away-the-bug solution.

Anyway, saying all this because I am not 100% sure that my analysis is
correct. Changing the function signature does appear to fix it though. Will
follow up with a patch.

It's a pity that we do not have a way to run unit tests on Windows builds.
I sometimes test mingw builds against some client-server setups, but msvc
builds may not be getting exercised enough --- especially with OpenSSL 3.0.

Thanks,

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] Fix auth-token usage with management-def-auth

2022-07-04 Thread Selva Nair
Hi

On Mon, Jul 4, 2022 at 5:50 AM Arne Schwabe  wrote:

> Am 04.07.22 um 04:58 schrieb selva.n...@gmail.com:
> > From: Selva Nair 
> >
> > When auth-token verify succeeds during a reauth, other auth
> > methods (plugin, script, management) are skipped unless
> > external-auth is in effect (skip_auth gets set to true).
> >
> > However, in this case, the status of management-def-auth
> > (ks->mda_satus) stays at its default value of ACF_PENDING
>
> ks->mda_status
>
> > and will never change. This causes TLS keys to go out of sync
> > and an eventual client disconnect.
> >
> > Further, a message saying username/password authentication is
> > "deferred" gets logged which is misleading.
> > For example:
> >
> > test/127.0.0.1:35874 TLS: Username/auth-token authentication
> >  succeeded for username 'test'
> >
> > followed by
> >
> > test/127.0.0.1:35874 TLS: Username/Password authentication
> >  deferred for username 'test' [CN SET]
> >
> > Fix by setting ks->mda_status to ACF_DISABLED, and do not
> > set ks->authenticated = KS_AUTH_DEFERRED when skip_auth is true.
> >
> > Also log a warning message when token is marked as expired on
> > missing the reneg window.
> >
> > Reported by: Connor Edwards 
> >
>
> Acked-By: Arne Schwabe 
>
> Note that you need have management enabled for this bug to trigger. If
> you go through all the effort to talk to management like this, you
> probably want to use external-auth anyway.
>

I agree. This kind of fiddling with flags like mda_status is not clean and
easy to break again. I use management-def-auth but do not use
auth-gen-token -- instead the management script keeps track of
reauth, lifetime of 2FA etc. If I were to "modernize" that setup I would
use auth-gen-token with external-auth as well.

That said, for 2.5, an easy fix like this is good enough?

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] Fix auth-token usage with management-def-auth

2022-07-03 Thread selva . nair
From: Selva Nair 

When auth-token verify succeeds during a reauth, other auth
methods (plugin, script, management) are skipped unless
external-auth is in effect (skip_auth gets set to true).

However, in this case, the status of management-def-auth
(ks->mda_satus) stays at its default value of ACF_PENDING
and will never change. This causes TLS keys to go out of sync
and an eventual client disconnect.

Further, a message saying username/password authentication is
"deferred" gets logged which is misleading.
For example:

test/127.0.0.1:35874 TLS: Username/auth-token authentication
succeeded for username 'test'

followed by

test/127.0.0.1:35874 TLS: Username/Password authentication
deferred for username 'test' [CN SET]

Fix by setting ks->mda_status to ACF_DISABLED, and do not
set ks->authenticated = KS_AUTH_DEFERRED when skip_auth is true.

Also log a warning message when token is marked as expired on
missing the reneg window.

Reported by: Connor Edwards 

Signed-off-by: Selva Nair 
---
 src/openvpn/auth_token.c | 8 +---
 src/openvpn/ssl_verify.c | 9 -
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/src/openvpn/auth_token.c b/src/openvpn/auth_token.c
index 096edc75..b5f9f6dd 100644
--- a/src/openvpn/auth_token.c
+++ b/src/openvpn/auth_token.c
@@ -346,20 +346,22 @@ verify_auth_token(struct user_pass *up, struct tls_multi 
*multi,
 return 0;
 }
 
-/* Accept session tokens that not expired are in the acceptable range
- * for renogiations */
+/* Accept session tokens only if their timestamp is in the acceptable range
+ * for renegotiations */
 bool in_renegotiation_time = now >= timestamp
  && now < timestamp + 2 * 
session->opt->renegotiate_seconds;
 
 if (!in_renegotiation_time)
 {
+msg(M_WARN, "Timestamp (%" PRIu64 ") of auth-token is out of the 
renegotiation window",
+timestamp);
 ret |= AUTH_TOKEN_EXPIRED;
 }
 
 /* Sanity check the initial timestamp */
 if (timestamp < timestamp_initial)
 {
-msg(M_WARN, "Initial timestamp (%" PRIu64 " in token from client 
earlier than "
+msg(M_WARN, "Initial timestamp (%" PRIu64 ") in token from client 
earlier than "
 "current timestamp %" PRIu64 ". Broken/unsynchronised clock?",
 timestamp_initial, timestamp);
 ret |= AUTH_TOKEN_EXPIRED;
diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c
index c01841fa..45eaf8ed 100644
--- a/src/openvpn/ssl_verify.c
+++ b/src/openvpn/ssl_verify.c
@@ -1599,7 +1599,14 @@ verify_user_pass(struct user_pass *up, struct tls_multi 
*multi,
 #ifdef ENABLE_MANAGEMENT
 if (man_def_auth != KMDA_UNDEF)
 {
-ks->authenticated = KS_AUTH_DEFERRED;
+if (skip_auth)
+{
+ks->mda_status = ACF_DISABLED;
+}
+else
+{
+ks->authenticated = KS_AUTH_DEFERRED;
+}
 }
 #endif
 if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME))
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] Remove management_write_peer_info_file and related code

2022-06-30 Thread selva . nair
From: Selva Nair 

Use of this has never been documented and the code was
dead for a long while now.

Signed-off-by: Selva Nair 
---

Alternative for [PATCH 2/3] Reactivate record_peer_info in manage.c

 src/openvpn/init.c|  1 -
 src/openvpn/manage.c  | 49 ---
 src/openvpn/manage.h  |  2 --
 src/openvpn/options.c |  5 +
 src/openvpn/options.h |  1 -
 5 files changed, 1 insertion(+), 57 deletions(-)

diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 03221cbb..1bfbf4eb 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -3862,7 +3862,6 @@ open_management(struct context *c)
 c->options.management_log_history_cache,
 c->options.management_echo_buffer_size,
 c->options.management_state_buffer_size,
-c->options.management_write_peer_info_file,
 c->options.remap_sigusr1,
 flags))
 {
diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c
index 50f162a3..19e44221 100644
--- a/src/openvpn/manage.c
+++ b/src/openvpn/manage.c
@@ -1614,48 +1614,6 @@ man_stop_ne32(struct management *man)
 
 #endif /* ifdef _WIN32 */
 
-static void
-man_record_peer_info(struct management *man)
-{
-struct gc_arena gc = gc_new();
-if (man->settings.write_peer_info_file)
-{
-bool success = false;
-#ifdef HAVE_GETSOCKNAME
-if (socket_defined(man->connection.sd_cli))
-{
-struct sockaddr_in addr;
-socklen_t addrlen = sizeof(addr);
-int status;
-
-CLEAR(addr);
-status = getsockname(man->connection.sd_cli, (struct sockaddr 
*), );
-if (!status && addrlen == sizeof(addr))
-{
-const in_addr_t a = ntohl(addr.sin_addr.s_addr);
-const int p = ntohs(addr.sin_port);
-FILE *fp = platform_fopen(man->settings.write_peer_info_file, 
"w");
-if (fp)
-{
-fprintf(fp, "%s\n%d\n", print_in_addr_t(a, 0, ), p);
-if (!fclose(fp))
-{
-success = true;
-}
-}
-}
-}
-#endif /* ifdef HAVE_GETSOCKNAME */
-if (!success)
-{
-msg(D_MANAGEMENT, "MANAGEMENT: failed to write peer info to file 
%s",
-man->settings.write_peer_info_file);
-throw_signal_soft(SIGTERM, "management-connect-failed");
-}
-}
-gc_free();
-}
-
 static void
 man_connection_settings_reset(struct management *man)
 {
@@ -1903,7 +1861,6 @@ man_connect(struct management *man)
 goto done;
 }
 
-man_record_peer_info(man);
 man_new_connection_post(man, "Connected to management server at");
 
 done:
@@ -2376,7 +2333,6 @@ man_settings_init(struct man_settings *ms,
   const int log_history_cache,
   const int echo_buffer_size,
   const int state_buffer_size,
-  const char *write_peer_info_file,
   const int remap_sigusr1,
   const unsigned int flags)
 {
@@ -2416,8 +2372,6 @@ man_settings_init(struct man_settings *ms,
 ASSERT(ms->client_gid >= 0);
 }
 
-ms->write_peer_info_file = string_alloc(write_peer_info_file, NULL);
-
 #if UNIX_SOCK_SUPPORT
 if (ms->flags & MF_UNIX_SOCK)
 {
@@ -2481,7 +2435,6 @@ man_settings_close(struct man_settings *ms)
 {
 freeaddrinfo(ms->local);
 }
-free(ms->write_peer_info_file);
 CLEAR(*ms);
 }
 
@@ -2584,7 +2537,6 @@ management_open(struct management *man,
 const int log_history_cache,
 const int echo_buffer_size,
 const int state_buffer_size,
-const char *write_peer_info_file,
 const int remap_sigusr1,
 const unsigned int flags)
 {
@@ -2603,7 +2555,6 @@ management_open(struct management *man,
   log_history_cache,
   echo_buffer_size,
   state_buffer_size,
-  write_peer_info_file,
   remap_sigusr1,
   flags);
 
diff --git a/src/openvpn/manage.h b/src/openvpn/manage.h
index 44a5d964..f46274e6 100644
--- a/src/openvpn/manage.h
+++ b/src/openvpn/manage.h
@@ -229,7 +229,6 @@ struct man_settings {
 int log_history_cache;
 int echo_buffer_size;
 int state_buffer_size;
-char *write_peer_info_file;
 int client_uid;
 int client_gid;
 
@@ -351,7 +350,6 @@ bool management_open(struct management *man,
  const int log_history_cache,
  const int echo_buffer_s

[Openvpn-devel] [PATCH 3/3] Log address of management client on accept

2022-06-30 Thread selva . nair
From: Selva Nair 

Currently when we are listening on the management
interface, the local address/port is logged as that of
the connecting client.

Fix it.

Signed-off-by: Selva Nair 
---
 src/openvpn/manage.c | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c
index 548d3b9a..7947c906 100644
--- a/src/openvpn/manage.c
+++ b/src/openvpn/manage.c
@@ -1685,9 +1685,27 @@ man_new_connection_post(struct management *man, const 
char *description)
 }
 else
 #endif
-msg(D_MANAGEMENT, "MANAGEMENT: %s %s",
-description,
-print_sockaddr(man->settings.local->ai_addr, ));
+if (man->settings.flags & MF_CONNECT_AS_CLIENT)
+{
+msg(D_MANAGEMENT, "MANAGEMENT: %s %s",
+description,
+print_sockaddr(man->settings.local->ai_addr, ));
+}
+else
+{
+struct sockaddr_storage addr;
+socklen_t addrlen = sizeof(addr);
+if (!getpeername(man->connection.sd_cli, (struct sockaddr *) ,
+ ))
+{
+msg(D_MANAGEMENT, "MANAGEMENT: %s %s", description,
+print_sockaddr((struct sockaddr *) , ));
+}
+else
+{
+msg(D_MANAGEMENT, "MANAGEMENT: %s %s", description, "unknown");
+}
+}
 
 buffer_list_reset(man->connection.out);
 
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 2/3] Reactivate record_peer_info in manage.c

2022-06-30 Thread selva . nair
From: Selva Nair 

--management-client has an obscure and undocumented feature
to take a file argument where the peer's address and port are
recorded. This has become dead code over time.

- reactivate the dead code
- make it work with v6 addresses as well
- do not exit on error in writing the record

Signed-off-by: Selva Nair 
---

Alternatively we could remove this "feature" and related code.

 src/openvpn/manage.c | 12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c
index 21c7ccdd..548d3b9a 100644
--- a/src/openvpn/manage.c
+++ b/src/openvpn/manage.c
@@ -1621,23 +1621,19 @@ man_record_peer_info(struct management *man)
 if (man->settings.write_peer_info_file)
 {
 bool success = false;
-#ifdef HAVE_GETSOCKNAME
 if (socket_defined(man->connection.sd_cli))
 {
-struct sockaddr_in addr;
+struct sockaddr_storage addr;
 socklen_t addrlen = sizeof(addr);
 int status;
 
-CLEAR(addr);
 status = getsockname(man->connection.sd_cli, (struct sockaddr 
*), );
-if (!status && addrlen == sizeof(addr))
+if (!status)
 {
-const in_addr_t a = ntohl(addr.sin_addr.s_addr);
-const int p = ntohs(addr.sin_port);
 FILE *fp = platform_fopen(man->settings.write_peer_info_file, 
"w");
 if (fp)
 {
-fprintf(fp, "%s\n%d\n", print_in_addr_t(a, 0, ), p);
+fprintf(fp, "%s\n", print_sockaddr((struct sockaddr 
*), ));
 if (!fclose(fp))
 {
 success = true;
@@ -1645,12 +1641,10 @@ man_record_peer_info(struct management *man)
 }
 }
 }
-#endif /* ifdef HAVE_GETSOCKNAME */
 if (!success)
 {
 msg(D_MANAGEMENT, "MANAGEMENT: failed to write peer info to file 
%s",
 man->settings.write_peer_info_file);
-throw_signal_soft(SIGTERM, "management-connect-failed");
 }
 }
 gc_free();
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 1/3] Log the actual management interface port in use

2022-06-30 Thread selva . nair
From: Selva Nair 

When the port is specified as zero, log the actual port
bound to, instead of 0.

Signed-off-by: Selva Nair 
---
 src/openvpn/manage.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c
index 50f162a3..21c7ccdd 100644
--- a/src/openvpn/manage.c
+++ b/src/openvpn/manage.c
@@ -1830,8 +1830,22 @@ man_listen(struct management *man)
 }
 else
 #endif
-msg(D_MANAGEMENT, "MANAGEMENT: TCP Socket listening on %s",
-print_sockaddr(man->settings.local->ai_addr, ));
+{
+const struct sockaddr *man_addr = man->settings.local->ai_addr;
+struct sockaddr_storage addr;
+socklen_t addrlen = sizeof(addr);
+if (!getsockname(man->connection.sd_top, (struct sockaddr *) 
, ))
+{
+man_addr = (struct sockaddr *) 
+}
+else
+{
+msg(M_WARN|M_ERRNO,
+"Failed to get the management socket address");
+}
+msg(D_MANAGEMENT, "MANAGEMENT: TCP Socket listening on %s",
+print_sockaddr(man_addr, ));
+}
 }
 
 #ifdef _WIN32
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH 19/25] dco-win: implement GetOverlappedResultEx for mingw32

2022-06-24 Thread Selva Nair
Hi,

On Fri, Jun 24, 2022 at 5:10 AM Antonio Quartulli  wrote:

> GetOverlappedResultEx is not available on ming32 therefore we must
> provide some compat layer before being able to use this function.
>

I suppose "mingw32" here refers to I mingw-w64 for 32 bit (i686) target.

This symbol has been exported in kernel32.lib since version 7.0 release of
mingw-w64 (~ 2019). Current release is version 10. Do we need to support
older versions given that mingw build is now used only for development by a
few of us?

I use debian which probably is the slowest to get new versions -- bullseye
has version 8 (gcc version 10), on buster I use unstable which gives
version 8. Ubuntu 20.04 has version 7, 22.04 has version 8.

Even if we must support 6.0 and older, let's not unconditionally use the
compat layer proposed here.


>
> Signed-off-by: Antonio Quartulli 
> Signed-off-by: Lev Stipakov 
> ---
>  src/compat/Makefile.am|  3 +-
>  src/compat/compat-dco_get_overlapped_result.c | 46 +++
>  src/compat/compat.h   |  8 
>  src/compat/compat.vcxproj |  1 +
>  src/compat/compat.vcxproj.filters |  3 ++
>  5 files changed, 60 insertions(+), 1 deletion(-)
>  create mode 100644 src/compat/compat-dco_get_overlapped_result.c
>
> diff --git a/src/compat/Makefile.am b/src/compat/Makefile.am
> index 6eb991dc..6dba08aa 100644
> --- a/src/compat/Makefile.am
> +++ b/src/compat/Makefile.am
> @@ -28,4 +28,5 @@ libcompat_la_SOURCES = \
> compat-gettimeofday.c \
> compat-daemon.c \
> compat-strsep.c \
> -   compat-versionhelpers.h
> +   compat-versionhelpers.h \
> +   compat-dco_get_overlapped_result.c
> diff --git a/src/compat/compat-dco_get_overlapped_result.c
> b/src/compat/compat-dco_get_overlapped_result.c
> new file mode 100644
> index ..e14ce976
> --- /dev/null
> +++ b/src/compat/compat-dco_get_overlapped_result.c
> @@ -0,0 +1,46 @@
> +/*
> + *  OpenVPN -- An application to securely tunnel IP networks
> + * over a single UDP port, with support for SSL/TLS-based
> + * session authentication and key exchange,
> + * packet encryption, packet authentication, and
> + * packet compression.
> + *
> + *  Copyright (C) 2021-2022 Lev Stipakov 
> + *  Copyright (C) 2021-2022 OpenVPN Inc 
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2
> + *  as published by the Free Software Foundation.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with this program (see the file COPYING included with this
> + *  distribution); if not, write to the Free Software Foundation, Inc.,
> + *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#elif defined(_MSC_VER)
> +#include "config-msvc.h"
> +#endif
> +
> +#include "compat.h"
> +
> +#if defined(__MINGW32__) && !defined(__MINGW64__)
> +BOOL
> +dco_get_overlapped_result(HANDLE handle, OVERLAPPED *ov, DWORD
> *transferred,
> +  DWORD delay_millisec, BOOL unused)
> +{
> +BOOL res = GetOverlappedResult(handle, ov, transferred, FALSE);
> +if ((res == 0) && (GetLastError() == ERROR_IO_INCOMPLETE))
> +{
> +Sleep(delay_millisec);


While this may be ok assuming it's not inside any performance critical
loops, no need to force this on newer versions of mingw-w64.

Alternatively, we could use AC_CHECK_FUNC to make this conditional or find
the symbol GetOverlappedResultEx at runtime. But, imo, we do not need any
of this as supporting mingw-w64 version 7+ should be enough.

Regards,

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] Add ability to specify initialize flags for pkcs11 provider

2022-06-23 Thread Selva Nair
Hi,

On Thu, Jun 23, 2022 at 8:43 AM David Sommerseth <
open...@sf.lists.topphemmelig.net> wrote:

> On 19/6/2022 19:28, Selva Nair wrote:
> > Hi,0
> >
> > On Thu, Sep 30, 2021 at 7:34 AM Petr Mikhalicin via Openvpn-devel
> >  > <mailto:openvpn-devel@lists.sourceforge.net>> wrote:
> >
> > New pkcs11-helper interface allows to setup pkcs11 provider via
> > properties:
> >
> https://github.com/alonbl/pkcs11-helper/commit/b78d21c7e26041746aa4ae3d08b95469e1714a85
> > <
> https://github.com/alonbl/pkcs11-helper/commit/b78d21c7e26041746aa4ae3d08b95469e1714a85
> >
> >
> > Also pkcs11-helper added ability to setup init args for pkcs11
> provider:
> >
> https://github.com/alonbl/pkcs11-helper/commit/133f893e30856eba1de715ecd6fe176722eb3097
> > <
> https://github.com/alonbl/pkcs11-helper/commit/133f893e30856eba1de715ecd6fe176722eb3097
> >
> >
> > Signed-off-by: Petr Mikhalicin  > <mailto:mkh199...@mail.ru>>
> >
> >
> > Sorry for the long delay in getting back on this. I somehow also missed
> > the related discussion on Trac
> > (https://community.openvpn.net/openvpn/ticket/1453
> > <https://community.openvpn.net/openvpn/ticket/1453>)
> >
> > I don't quite understand the need for exposing "init-args" to the user.
> > The only two supported flags in the cryptoki docs are related to the use
> > of threads. But we are the application and we should know what flags to
> > pass --- not the user --- isn't it? If CKF_OS_LOCKING_OK is required,
> > can't we just set it unconditionally?
> >
> > That said, OpenVPN2 is single threaded, so why is there a "bug in
> > openvpn" related to the use of pkcs11 library from multiple threads
> > referred to in the trac ticket?
>
> I haven't dug too deep into the matter this time; and it depends also on
> the OS you are on.  But there has been some issues with pkcs11-helper on
> hosts with systemd, due to some intricacies with openvpn doing a fork to
> kick off the password query mechanism with systemd colliding with some
> pkcs11-helper implementation details.  For the systemd case, we added a
> workaround which made most people happy.
>
> For more details:
> <https://community.openvpn.net/openvpn/ticket/538>
>

This is a different issue from  mutex locking required when  pkcs#11  calls
are made from multiple threads. The rationale for this patch was that we
may need to tell the provider library whether native OS locking methods are
okay or not, which I see no need for in a single threaded program.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] Add ability to specify initialize flags for pkcs11 provider

2022-06-19 Thread Selva Nair
Hi,

On Thu, Sep 30, 2021 at 7:34 AM Petr Mikhalicin via Openvpn-devel <
openvpn-devel@lists.sourceforge.net> wrote:

> New pkcs11-helper interface allows to setup pkcs11 provider via
> properties:
> https://github.com/alonbl/pkcs11-helper/commit/b78d21c7e26041746aa4ae3d08b95469e1714a85
>
> Also pkcs11-helper added ability to setup init args for pkcs11 provider:
>
> https://github.com/alonbl/pkcs11-helper/commit/133f893e30856eba1de715ecd6fe176722eb3097
>
> Signed-off-by: Petr Mikhalicin 
>

Sorry for the long delay in getting back on this. I somehow also missed the
related discussion on Trac (
https://community.openvpn.net/openvpn/ticket/1453)

I don't quite understand the need for exposing "init-args" to the user. The
only two supported flags in the cryptoki docs are related to the use of
threads. But we are the application and we should know what flags to pass
--- not the user --- isn't it? If CKF_OS_LOCKING_OK is required, can't we
just set it unconditionally?

That said, OpenVPN2 is single threaded, so why is there a "bug in openvpn"
related to the use of pkcs11 library from multiple threads referred to in
the trac ticket?

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v3] Implement ED448 and ED25519 support in xkey_provider

2022-05-16 Thread Selva Nair
Hi,

Thanks for the new version. Looks good (only compile tested).

Acked-by: Selva Nair 




Selva

On Mon, May 16, 2022 at 6:49 AM Arne Schwabe  wrote:
>
> OpenSSL's implementation of ED448 and ED25519 has a few idiosyncrasies.
> Instead of belonging to the elliptic curve type or to a common Edwards
> curve type, ED448 and ED25519 have each their own type.
>
> Also, OpenSSL expects signatures using these curves to be done with the
> EVP_DigestSign API instead of the EVP_Sign API but using md=NULL.
>
> This has been tested using a "fake" external key that used a normal
> software key instead of a hardware implementation but that makes no
> difference from the perspective of xkey_provider/management interface.
>
> Patch v2: remove name functions from ed448/ed25519, ensure md is NULL
>   for ed448/ed25519 and handle NULL/none better in general.
>
> Patch v3: do not pass NULL as string for the OSSL params.
> ---
>  src/openvpn/xkey_common.h|  2 +-
>  src/openvpn/xkey_helper.c|  7 +-
>  src/openvpn/xkey_provider.c  | 97 ++--
>  tests/unit_tests/openvpn/test_provider.c | 36 +++--
>  4 files changed, 126 insertions(+), 16 deletions(-)
>
> diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h
> index 35cbcf576..e0e5ed5b2 100644
> --- a/src/openvpn/xkey_common.h
> +++ b/src/openvpn/xkey_common.h
> @@ -43,7 +43,7 @@ OSSL_provider_init_fn xkey_provider_init;
>  #define XKEY_PROV_PROPS "provider=ovpn.xkey"
>
>  /**
> - * Stuct to encapsulate signature algorithm parameters to pass
> + * Struct to encapsulate signature algorithm parameters to pass
>   * to sign operation.
>   */
>  typedef struct {
> diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c
> index ecc7b1204..c1b1dfdbf 100644
> --- a/src/openvpn/xkey_helper.c
> +++ b/src/openvpn/xkey_helper.c
> @@ -179,7 +179,8 @@ xkey_management_sign(void *unused, unsigned char *sig, 
> size_t *siglen,
>  bool is_message = !strcmp(alg.op, "DigestSign"); /* tbs is message, not 
> digest */
>
>  /* if management client cannot do digest -- we do it here */
> -if (!strcmp(alg.op, "DigestSign") && !(flags & MF_EXTERNAL_KEY_DIGEST))
> +if (!strcmp(alg.op, "DigestSign") && !(flags & MF_EXTERNAL_KEY_DIGEST)
> +&& strcmp(alg.mdname, "none"))
>  {
>  dmsg(D_XKEY, "xkey_management_sign: computing digest");
>  if (xkey_digest(tbs, tbslen, buf, , alg.mdname))
> @@ -206,6 +207,10 @@ xkey_management_sign(void *unused, unsigned char *sig, 
> size_t *siglen,
>  openvpn_snprintf(alg_str, sizeof(alg_str), "ECDSA,hashalg=%s", 
> alg.mdname);
>  }
>  }
> +else if (!strcmp(alg.keytype, "ED448") || !strcmp(alg.keytype, 
> "ED25519"))
> +{
> +strncpynt(alg_str, alg.keytype, sizeof(alg_str));
> +}
>  /* else assume RSA key */
>  else if (!strcmp(alg.padmode, "pkcs1") && (flags & 
> MF_EXTERNAL_KEY_PKCS1PAD))
>  {
> diff --git a/src/openvpn/xkey_provider.c b/src/openvpn/xkey_provider.c
> index 46e57e0fe..6704e 100644
> --- a/src/openvpn/xkey_provider.c
> +++ b/src/openvpn/xkey_provider.c
> @@ -99,12 +99,28 @@ typedef struct
>  int refcount;/**< reference count */
>  } XKEY_KEYDATA;
>
> -static int
> -KEYTYPE(const XKEY_KEYDATA *key)
> +static inline const char *
> +get_keytype(const XKEY_KEYDATA *key)
>  {
> -return key->pubkey ? EVP_PKEY_get_id(key->pubkey) : 0;
> +int keytype = key->pubkey ? EVP_PKEY_get_id(key->pubkey) : 0;
> +
> +switch (keytype)
> +{
> +case EVP_PKEY_RSA:
> +return "RSA";
> +
> +case EVP_PKEY_ED448:
> +return "ED448";
> +
> +case EVP_PKEY_ED25519:
> +return "ED25519";
> +
> +default:
> +return "EC";
> +}
>  }
>
> +
>  static int
>  KEYSIZE(const XKEY_KEYDATA *key)
>  {
> @@ -310,6 +326,22 @@ ec_keymgmt_import(void *keydata, int selection, const 
> OSSL_PARAM params[])
>  return keymgmt_import(keydata, selection, params, "EC");
>  }
>
> +static int
> +ed448_keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[])
> +{
> +xkey_dmsg(D_XKEY, "entry");
> +
> +return keymgmt_import(keydata, selection, params, "ED448");
> +}
> +
> +static int
> +ed25519_keymgmt_import(void *keydata, int selection, const OSSL_PARAM 
> params[])
> +{

Re: [Openvpn-devel] [PATCH v2] Implement ED448 and ED25519 support in xkey_provider

2022-05-14 Thread Selva Nair
Hi,

Thanks for the v2. I'm ready to ack this but for one issue (NULL
passed to OSSL_PARAM_construct_utf8_string).

On Fri, May 13, 2022 at 9:05 AM Arne Schwabe  wrote:
>
> OpenSSL's implementation of ED448 and ED25519 has a few idiosyncrasies.
> Instead of belonging to the eliptic curve type or to a common Edwards

nit: elliptic (sorry I missed this earlier).

> curve type, ED448 and ED25519 have each their own type.
>
> Also, OpenSSL expects signatures using these curves to be done with the
> EVP_DigestSign API instead of the EVP_Sign API but using md=NULL.
>
> This has been tested using a "fake" external key that used a normal
> software key instead of a hardware implementation but that makes no
> difference from the perspective of xkey_provider/management interface.
>
> Patch v2: remove name functions from ed448/ed25519, ensure md is NULL
>   for ed448/ed25519 and handle NULL/none better in general.
> ---
>  src/openvpn/xkey_common.h|  2 +-
>  src/openvpn/xkey_helper.c|  7 +-
>  src/openvpn/xkey_provider.c  | 97 ++--
>  tests/unit_tests/openvpn/test_provider.c | 37 +++--
>  4 files changed, 127 insertions(+), 16 deletions(-)
>
> diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h
> index 35cbcf576..e0e5ed5b2 100644
> --- a/src/openvpn/xkey_common.h
> +++ b/src/openvpn/xkey_common.h
> @@ -43,7 +43,7 @@ OSSL_provider_init_fn xkey_provider_init;
>  #define XKEY_PROV_PROPS "provider=ovpn.xkey"
>
>  /**
> - * Stuct to encapsulate signature algorithm parameters to pass
> + * Struct to encapsulate signature algorithm parameters to pass
>   * to sign operation.
>   */
>  typedef struct {
> diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c
> index ecc7b1204..f47f7ffc7 100644
> --- a/src/openvpn/xkey_helper.c
> +++ b/src/openvpn/xkey_helper.c
> @@ -179,7 +179,8 @@ xkey_management_sign(void *unused, unsigned char *sig, 
> size_t *siglen,
>  bool is_message = !strcmp(alg.op, "DigestSign"); /* tbs is message, not 
> digest */
>
>  /* if management client cannot do digest -- we do it here */
> -if (!strcmp(alg.op, "DigestSign") && !(flags & MF_EXTERNAL_KEY_DIGEST))
> +if (!strcmp(alg.op, "DigestSign") && !(flags & MF_EXTERNAL_KEY_DIGEST)
> +&& strcmp(alg.mdname, "none") != 0)

nit: Why not strcmp(alg.mdname, "none")? That's how we use it
elsewhere in the patch and this file. Unless our coding style now
requires this.

>  {
>  dmsg(D_XKEY, "xkey_management_sign: computing digest");
>  if (xkey_digest(tbs, tbslen, buf, , alg.mdname))
> @@ -206,6 +207,10 @@ xkey_management_sign(void *unused, unsigned char *sig, 
> size_t *siglen,
>  openvpn_snprintf(alg_str, sizeof(alg_str), "ECDSA,hashalg=%s", 
> alg.mdname);
>  }
>  }
> +else if (!strcmp(alg.keytype, "ED448") || !strcmp(alg.keytype, 
> "ED25519"))
> +{
> +strncpynt(alg_str, alg.keytype, sizeof(alg_str));
> +}
>  /* else assume RSA key */
>  else if (!strcmp(alg.padmode, "pkcs1") && (flags & 
> MF_EXTERNAL_KEY_PKCS1PAD))
>  {
> diff --git a/src/openvpn/xkey_provider.c b/src/openvpn/xkey_provider.c
> index 46e57e0fe..6704e 100644
> --- a/src/openvpn/xkey_provider.c
> +++ b/src/openvpn/xkey_provider.c
> @@ -99,12 +99,28 @@ typedef struct
>  int refcount;/**< reference count */
>  } XKEY_KEYDATA;
>
> -static int
> -KEYTYPE(const XKEY_KEYDATA *key)
> +static inline const char *
> +get_keytype(const XKEY_KEYDATA *key)
>  {
> -return key->pubkey ? EVP_PKEY_get_id(key->pubkey) : 0;
> +int keytype = key->pubkey ? EVP_PKEY_get_id(key->pubkey) : 0;
> +
> +switch (keytype)
> +{
> +case EVP_PKEY_RSA:
> +return "RSA";
> +
> +case EVP_PKEY_ED448:
> +return "ED448";
> +
> +case EVP_PKEY_ED25519:
> +return "ED25519";
> +
> +default:
> +return "EC";
> +}
>  }
>
> +
>  static int
>  KEYSIZE(const XKEY_KEYDATA *key)
>  {
> @@ -310,6 +326,22 @@ ec_keymgmt_import(void *keydata, int selection, const 
> OSSL_PARAM params[])
>  return keymgmt_import(keydata, selection, params, "EC");
>  }
>
> +static int
> +ed448_keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[])
> +{
> +xkey_dmsg(D_XKEY, "entry");
> +
> +return keymgmt_import(keydata, selection, params, "ED448");
> +}
> +
> +static int
> +ed25519_keymgmt_import(void *keydata, int selection, const OSSL_PARAM 
> params[])
> +{
> +xkey_dmsg(D_XKEY, "entry");
> +
> +return keymgmt_import(keydata, selection, params, "ED25519");
> +}
> +
>  /* This function has to exist for key import to work
>   * though we do not support import of individual params
>   * like n or e. We simply return an empty list here for
> @@ -449,7 +481,7 @@ keymgmt_import_helper(XKEY_KEYDATA *key, const OSSL_PARAM 
> *params)
>  ASSERT(pkey);
>
>  int id = EVP_PKEY_get_id(pkey);
> -

Re: [Openvpn-devel] [PATCH release/2.5] Fix M_ERRNO behavior on Windows

2022-05-11 Thread Selva Nair
Acked-by: Selva Nair 

Same as the patch 2429 <https://patchwork.openvpn.net/patch/2429/> for
master except for the minor change in x_check_status() to match 2.5.

On Wed, May 4, 2022 at 5:13 AM Lev Stipakov  wrote:

> From: Lev Stipakov 
>
> We use M_ERRNO flag in logging to display error code
> and error message. This has been broken on Windows,
> where we use error code from GetLastError() and
> error description from strerror(). strerror() expects
> C runtime error code, which is quite different from
> last error code from WinAPI call. As a result, we got
> incorrect error description.
>
> The ultimate fix would be introducing another flag
> for WinAPI errors, like M_WINERR and use either that or
> M_ERRNO depends on context. However, the change would be
> quite intrusive and in some cases it is hard to say which
> one to use without looking into internals.
>
> Instead we stick to M_ERRNO and in Windows case we
> first try to obtain error code from GetLastError() and
> if it returns ERROR_SUCCESS (which is 0), we assume that
> we have C runtime error and use errno. To get error
> description we use strerror_win32() with GetLastError()
> and strerror() with errno.
>
> strerror_win32() uses FormatMessage() internally, which
> is the right way to get WinAPI error description.
> ---
>
>  This is a backport of patch acked for master
> (https://patchwork.openvpn.net/patch/2429/) with
> a conflict resolved in x_check_status() in error.c.
>
>  src/openvpn/error.c| 32 +---
>  src/openvpn/error.h| 39 +--
>  src/openvpn/forward.c  |  9 -
>  src/openvpn/manage.c   |  5 +++--
>  src/openvpn/platform.c |  2 +-
>  src/openvpn/tun.h  |  4 ++--
>  6 files changed, 68 insertions(+), 23 deletions(-)
>
> diff --git a/src/openvpn/error.c b/src/openvpn/error.c
> index 54796d03..7fbda844 100644
> --- a/src/openvpn/error.c
> +++ b/src/openvpn/error.c
> @@ -220,6 +220,18 @@ x_msg(const unsigned int flags, const char *format,
> ...)
>  va_end(arglist);
>  }
>
> +static const char*
> +openvpn_strerror(int err, bool crt_error, struct gc_arena *gc)
> +{
> +#ifdef _WIN32
> +if (!crt_error)
> +{
> +return strerror_win32(err, gc);
> +}
> +#endif
> +return strerror(err);
> +}
> +
>  void
>  x_msg_va(const unsigned int flags, const char *format, va_list arglist)
>  {
> @@ -244,7 +256,8 @@ x_msg_va(const unsigned int flags, const char *format,
> va_list arglist)
>  }
>  #endif
>
> -e = openvpn_errno();
> +bool crt_error = false;
> +e = openvpn_errno_maybe_crt(_error);
>
>  /*
>   * Apply muting filter.
> @@ -268,7 +281,7 @@ x_msg_va(const unsigned int flags, const char *format,
> va_list arglist)
>  if ((flags & M_ERRNO) && e)
>  {
>  openvpn_snprintf(m2, ERR_BUF_SIZE, "%s: %s (errno=%d)",
> - m1, strerror(e), e);
> + m1, openvpn_strerror(e, crt_error, ), e);
>  SWAP;
>  }
>
> @@ -649,7 +662,6 @@ x_check_status(int status,
> struct link_socket *sock,
> struct tuntap *tt)
>  {
> -const int my_errno = openvpn_errno();
>  const char *extended_msg = NULL;
>
>  msg(x_cs_verbose_level, "%s %s returned %d",
> @@ -672,26 +684,32 @@ x_check_status(int status,
>  sock->info.mtu_changed = true;
>  }
>  }
> -#elif defined(_WIN32)
> +#endif /* EXTENDED_SOCKET_ERROR_CAPABILITY */
> +
> +#ifdef _WIN32
>  /* get possible driver error from TAP-Windows driver */
>  if (tuntap_defined(tt))
>  {
>  extended_msg = tap_win_getinfo(tt, );
>  }
>  #endif
> -if (!ignore_sys_error(my_errno))
> +
> +bool crt_error = false;
> +int my_errno = openvpn_errno_maybe_crt(_error);
> +
> +if (!ignore_sys_error(my_errno, crt_error))
>  {
>  if (extended_msg)
>  {
>  msg(x_cs_info_level, "%s %s [%s]: %s (code=%d)",
> description,
>  sock ? proto2ascii(sock->info.proto, sock->info.af,
> true) : "",
> -extended_msg, strerror(my_errno), my_errno);
> +extended_msg, openvpn_strerror(my_errno, crt_error,
> ), my_errno);
>  }
>  else
>  {
>  msg(x_cs_info_level, "%s %s: %s (code=%d)", description,
>  sock ? proto2ascii(sock->info.proto, sock->info.af,
> true) : "",
&

Re: [Openvpn-devel] [PATCH] Implement ED448 and ED25519 support in xkey_provider

2022-05-11 Thread Selva Nair
>  sctx->keydata = provkey; /* used by digest_sign */
>  sctx->keydata->refcount++;
> -sctx->sigalg.keytype = KEYTYPE(sctx->keydata) == EVP_PKEY_RSA ? "RSA"
> : "EC";
> +sctx->sigalg.keytype = get_keytype(sctx->keydata);
>
>  signature_set_ctx_params(ctx, params);
>  if (mdname)
>  {
>  sctx->sigalg.mdname = xkey_mdname(mdname); /* get a string
> literal pointer */
>  }
> +else if (!strcmp(sctx->sigalg.keytype, "ED448") ||
> !strcmp(sctx->sigalg.keytype, "ED25519"))
> +{
> +/* EdDSA requires NULL as digest for the DigestSign API instead
> + * of using the normal Sign API */
> +sctx->sigalg.mdname = "none";
> +}
>

Instead of this order, we have to assert that mdname must be NULL if
keytype is ED25519 or ED448. OpenSSL does not impose this when the key is
in provider, but docs for EVP_DigestSignInit() says mdname should be NULL
for such keys. So I think we should return an error if mdname is not NULL.

In fact we do call EVP_DigestSignInit() in our unit test with mdname=SHA256
and Ed25519 key (after this patch) which exposes this issue (see below).


>  else
>  {
>  msg(M_WARN, "xkey digest_sign_init: mdname is NULL.");
> @@ -1073,6 +1180,8 @@ static const OSSL_DISPATCH signature_functions[] = {
>  const OSSL_ALGORITHM signatures[] = {
>  {"RSA:rsaEncryption", XKEY_PROV_PROPS, signature_functions, "OpenVPN
> xkey RSA Signature"},
>  {"ECDSA", XKEY_PROV_PROPS, signature_functions, "OpenVPN xkey ECDSA
> Signature"},
> +{"ED448", XKEY_PROV_PROPS, signature_functions, "OpenVPN xkey Ed448
> Signature"},
> +{"ED25519", XKEY_PROV_PROPS, signature_functions, "OpenVPN xkey
> Ed25519 Signature"},
>  {NULL, NULL, NULL, NULL}
>  };
>
> diff --git a/tests/unit_tests/openvpn/test_provider.c
> b/tests/unit_tests/openvpn/test_provider.c
> index 0b0952ee2..e29252838 100644
> --- a/tests/unit_tests/openvpn/test_provider.c
> +++ b/tests/unit_tests/openvpn/test_provider.c
> @@ -66,7 +66,11 @@ static const char *const pubkey2 = "-BEGIN PUBLIC
> KEY-\n"
>
> "u95ff1JiUaJIkYNIkZA+hwIPFVH5aJcSCv3SPIeDS2VUAESNKHZJBQ==\n"
> "-END PUBLIC KEY-\n";
>
> -static const char *pubkeys[] = {pubkey1, pubkey2};
> +static const char *const pubkey3 = "-BEGIN PUBLIC KEY-\n"
> +
>  "MCowBQYDK2VwAyEA+q5xjF5hGyyqYZidJdz/0saEQabL3N4wIZJBxNGbgJE=\n"
> +   "-END PUBLIC KEY-";
> +
> +static const char *pubkeys[] = {pubkey1, pubkey2, pubkey3};
>
>  static const char *prov_name = "ovpn.xkey";
>
> @@ -158,12 +162,17 @@ management_query_pk_sig(struct management *man,
> const char *b64_data,
>  if (strstr(algorithm, "data=message"))
>  {
>  expected_tbs = test_msg_b64;
> -assert_non_null(strstr(algorithm, "hashalg=SHA256"));
> +/* ED25519 does not have a hash algorithm even though it goes via

+ * the DigestSign path (data=message) */
> +if (!strstr(algorithm, "ED25519"))
> +{
> +assert_non_null(strstr(algorithm, "hashalg=SHA256"));
> +}

 }
>  assert_string_equal(b64_data, expected_tbs); Though it still uses
> digestSign()
>
> -/* We test using ECDSA or PSS with saltlen = digest */
> -if (!strstr(algorithm, "ECDSA"))
> +/* We test using ED25519, ECDSA or PSS with saltlen = digest */
> +if (!strstr(algorithm, "ECDSA") && !strstr(algorithm, "ED25519"))
>  {
>  assert_non_null(strstr(algorithm,
> "RSA_PKCS1_PSS_PADDING,hashalg=SHA256,saltlen=digest"));
>  }
> @@ -328,13 +337,13 @@ xkey_sign(void *handle, unsigned char *sig, size_t
> *siglen,
>  assert_memory_equal(tbs, test_digest, sizeof(test_digest));
>  }
>
> -/* For the test use sha256 and PSS padding for RSA */
> +/* For the test use sha256 and PSS padding for RSA and none for EDDSA
> */
>  assert_int_equal(OBJ_sn2nid(s.mdname), NID_sha256);
>

This works now because we wrongly call Ed25519 signature with mdname=sha256
in the test. I think we want this to be something like

 if (!strcmp(s.keytype, "ED25519"))
 {
 assert_string_equal(s.mdname, "none");
 }
else
{
assert_int_equal(OBJ_sn2nid(s.mdname), NID_sha256);
}

And, in digest_sign() we want to set mdname=NULL for Ed25519 key.. Like:

diff --git a/tests/unit_tests/openvpn/test_provider.c
b/tests/unit_tests/openvpn/test_provider.c
index e2925283..aa2ac7b9 100644
--- a/tests/unit_tests/openvpn/test_provider.c
+++ b/tests/unit_tests/openvpn/test_provider.c
@@ -237,6 +237,10 @@ digest_sign(EVP_PKEY *pkey)
 params[3] =
OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, (char
*)saltlen, 0);
 params[4] = OSSL_PARAM_construct_end();
 }
+else if (EVP_PKEY_get_id(pkey) == EVP_PKEY_ED25519)
+{
+mdname = NULL;
+}


 if (!strcmp(s.keytype, "RSA"))
>  {
>  assert_string_equal(s.padmode, "pss"); /* we use PSS for the test
> */
>  }
> -else if (strcmp(s.keytype, "EC"))
> +else if (strcmp(s.keytype, "EC") && strcmp(s.keytype,"ED25519"))
>  {
>  fail_msg("Unknown keytype: %s", s.keytype);
>  }
>

Finally, xkey_management_sign() in xkey_helper.c should not call
xkey_digest() if mdname is "none". So line 182 in xkey_helper.c will have
to become something like:

if (!strcmp(alg.op, "DigestSign") && !(flags & MF_EXTERNAL_KEY_DIGEST) &&
strcmp(alg.mdname,"none"))

All look good otherwise.

Regards,

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v2] Fix M_ERRNO behavior on Windows

2022-05-03 Thread Selva Nair
o, sock->info.af,
> true) : "",
> -strerror(my_errno), sock ? sock->sd : -1, my_errno);
> +openvpn_strerror(my_errno, crt_error, ),
> +sock ? sock->sd : -1, my_errno);
>  }
>
>  if (x_cs_err_delay_ms)
> diff --git a/src/openvpn/error.h b/src/openvpn/error.h
> index ad7defe8..be8d97e5 100644
> --- a/src/openvpn/error.h
> +++ b/src/openvpn/error.h
> @@ -75,13 +75,10 @@ struct gc_arena;
>  /* String and Error functions */
>
>  #ifdef _WIN32
> -#define openvpn_errno() GetLastError()
> -#define openvpn_strerror(e, gc) strerror_win32(e, gc)
> +#define openvpn_errno() GetLastError()
>  const char *strerror_win32(DWORD errnum, struct gc_arena *gc);
> -
>  #else
> -#define openvpn_errno() errno
> -#define openvpn_strerror(x, gc) strerror(x)
> +#define openvpn_errno() errno
>  #endif
>
>  /*
> @@ -352,20 +349,22 @@ msg_get_virtual_output(void)
>   * which can be safely ignored.
>   */
>  static inline bool
> -ignore_sys_error(const int err)
> +ignore_sys_error(const int err, bool crt_error)
>  {
> -/* I/O operation pending */
>  #ifdef _WIN32
> -if (err == WSAEWOULDBLOCK || err == WSAEINVAL)
> +if (!crt_error && ((err == WSAEWOULDBLOCK || err == WSAEINVAL)))
>  {
>  return true;
>  }
>  #else
> -if (err == EAGAIN)
> +crt_error = true;
> +#endif
> +
> +/* I/O operation pending */
> +if (crt_error && (err == EAGAIN))
>  {
>  return true;
>  }
> -#endif
>
>  #if 0 /* if enabled, suppress ENOBUFS errors */
>  #ifdef ENOBUFS
> @@ -387,6 +386,26 @@ nonfatal(const unsigned int err)
>  return err & M_FATAL ? (err ^ M_FATAL) | M_NONFATAL : err;
>  }
>
> +static inline int
> +openvpn_errno_maybe_crt(bool *crt_error)
> +{
> +int err = 0;
> +*crt_error = false;
> +#ifdef _WIN32
> +err = GetLastError();
> +if (err == ERROR_SUCCESS)
> +{
> +/* error is likely C runtime */
> +*crt_error = true;
> +err = errno;
> +}
> +#else
> +*crt_error = true;
> +err = errno;
> +#endif
> +return err;
> +}
> +
>  #include "errlevel.h"
>
>  #endif /* ifndef ERROR_H */
> diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
> index 8930e578..04828a5c 100644
> --- a/src/openvpn/forward.c
> +++ b/src/openvpn/forward.c
> @@ -1660,7 +1660,14 @@ process_outgoing_link(struct context *c)
>  }
>
>  /* for unreachable network and "connecting" state switch to the
> next host */
> -if (size < 0 && ENETUNREACH == error_code && c->c2.tls_multi
> +
> +bool unreachable = error_code ==
> +#ifdef _WIN32
> +WSAENETUNREACH;
> +#else
> +ENETUNREACH;
> +#endif
> +if (size < 0 && unreachable && c->c2.tls_multi
>  && !tls_initial_packet_received(c->c2.tls_multi) &&
> c->options.mode == MODE_POINT_TO_POINT)
>  {
>  msg(M_INFO, "Network unreachable, restarting");
> diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c
> index 9b03b057..036658b1 100644
> --- a/src/openvpn/manage.c
> +++ b/src/openvpn/manage.c
> @@ -2008,9 +2008,10 @@ man_process_command(struct management *man, const
> char *line)
>  static bool
>  man_io_error(struct management *man, const char *prefix)
>  {
> -const int err = openvpn_errno();
> +bool crt_error = false;
> +int err = openvpn_errno_maybe_crt(_error);
>
> -if (!ignore_sys_error(err))
> +if (!ignore_sys_error(err, crt_error))
>  {
>  struct gc_arena gc = gc_new();
>  msg(D_MANAGEMENT, "MANAGEMENT: TCP %s error: %s", prefix,
> diff --git a/src/openvpn/platform.c b/src/openvpn/platform.c
> index 61afee83..ae1678db 100644
> --- a/src/openvpn/platform.c
> +++ b/src/openvpn/platform.c
> @@ -532,7 +532,7 @@ platform_test_file(const char *filename)
>  }
>  else
>  {
> -if (openvpn_errno() == EACCES)
> +if (errno == EACCES)
>  {
>  msg( M_WARN | M_ERRNO, "Could not access file '%s'",
> filename);
>  }
> diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h
> index 3a7314c5..4bc35916 100644
> --- a/src/openvpn/tun.h
> +++ b/src/openvpn/tun.h
> @@ -446,7 +446,7 @@ tuntap_stop(int status)
>   */
>  if (status < 0)
>  {
> -return openvpn_errno() == ERROR_FILE_NOT_FOUND;
> +return GetLastError() == ERROR_FILE_NOT_FOUND;
>  }
>  return false;
>  }
> @@ -459,7 +459,7 @@ tuntap_abort(int status)
>   */
>  if (status < 0)
>  {
> -return openvpn_errno() == ERROR_OPERATION_ABORTED;
> +return GetLastError() == ERROR_OPERATION_ABORTED;
>  }
>  return false;
>  }
>

Acked-by: Selva Nair 
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] Fix M_ERRNO behavior on Windows

2022-04-22 Thread Selva Nair
ror? */
>  if (size != 1)
>  {
> -msg(D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read
> failed on recv()");
> +msg(D_LINK_ERRORS | M_SKERR, "socks_handshake: TCP port read
> failed on recv()");
>  return false;
>  }
>
> @@ -342,14 +342,14 @@ recv_socks_reply(socket_descriptor_t sd,
>  /* timeout? */
>  if (status == 0)
>  {
> -msg(D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read
> timeout expired");
> +msg(D_LINK_ERRORS | M_SKERR, "recv_socks_reply: TCP port read
> timeout expired");
>  return false;
>  }
>
>  /* error */
>  if (status < 0)
>  {
> -msg(D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read
> failed on select()");
> +msg(D_LINK_ERRORS | M_SKERR, "recv_socks_reply: TCP port read
> failed on select()");
>  return false;
>  }
>
> @@ -359,7 +359,7 @@ recv_socks_reply(socket_descriptor_t sd,
>  /* error? */
>  if (size != 1)
>  {
> -msg(D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read
> failed on recv()");
> +msg(D_LINK_ERRORS | M_SKERR, "recv_socks_reply: TCP port read
> failed on recv()");
>  return false;
>  }
>
> @@ -484,7 +484,7 @@ establish_socks_proxy_passthru(struct socks_proxy_info
> *p,
>  const ssize_t size = send(sd, buf, 5 + len + 2, MSG_NOSIGNAL);
>  if ((int)size != 5 + (int)len + 2)
>  {
> -msg(D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru:
> TCP port write failed on send()");
> +msg(D_LINK_ERRORS | M_SKERR, "establish_socks_proxy_passthru:
> TCP port write failed on send()");
>  goto error;
>  }
>  }
> @@ -527,7 +527,7 @@ establish_socks_proxy_udpassoc(struct socks_proxy_info
> *p,
>10, MSG_NOSIGNAL);
>  if (size != 10)
>  {
> -msg(D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru:
> TCP port write failed on send()");
> +msg(D_LINK_ERRORS | M_SKERR, "establish_socks_proxy_passthru:
> TCP port write failed on send()");
>  goto error;
>  }
>  }
> --
>

All that said, it may be hard to get all error reporting fixed in one
patch, so we could proceed in steps. First make openvpn_errno() and
openvpn_strerror() do the right thing with GetLastError() vs errno, then
fix WSA error printing, then the rest if any. Just a thought.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] OpenVPN Client 2FA problem with Backslash

2022-03-11 Thread Selva Nair
Hi Jacob,

On Fri, Mar 11, 2022 at 3:52 AM Jakob Curdes  wrote:

> Hello Selva, hello all,
>
> I have tested the executable in the circumstances described earlier. I
> confirm the problem described (username/password auth succeeds, but second
> auth with 2FA data fails as the backslash in the username is not escaped
> this time) is solved using the binary provided. I also confirmed this in
> issue #483  .
>
> Thank you all for your quick work. This will help us rolling out 2FA to a
> bunch of users!
>
Thanks for testing.

Selva

>
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] OpenVPN Client 2FA problem with Backslash

2022-03-10 Thread Selva Nair
Hi,

On Thu, Mar 10, 2022 at 4:23 PM Gert Doering  wrote:

> Hi,
>
> On Thu, Mar 10, 2022 at 12:51:51PM -0500, Selva Nair wrote:
> > I missed this follow up on the devel list. Please see my reply to
> > openvpn-users. If @ doesnt work there is no easy fix short of patching
> the
> > GUI.
>
> We're planning a 2.5.x release "some time next week" (partly prompted
> due to the OpenSSL release on

tuesday).  So now's a good time for GUI
> fixes :-)
>
>
See PR 483 <https://github.com/OpenVPN/openvpn-gui/pull/483>

@Jakob Curdes   This could be tested using the CI
executable here:
https://github.com/OpenVPN/openvpn-gui/suites/5617977743/artifacts/182849130
(for 64 bit Windows). No need to install --- just unzip into a temp folder
and double click on the included openvpn-gui.exe.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] OpenVPN Client 2FA problem with Backslash

2022-03-10 Thread Selva Nair
Hi,

On Thu, Mar 10, 2022 at 9:15 AM Jakob Curdes  wrote:

> Hello all,
>
> I think I have found a bug in the OpenVPN Windows client , can you help me
> to determine if this is true and how to proceed?
>
> We are trying to implement 2FA for several existing Firebox SSL VPNs
> (which essentially uses OpenVPN on server and client side). The remote
> users all use the Windows OpenVPN client. This works perfectly without 2FA,
> and it works also if you do not need to specify the authentication domain
> on user logon. But for the migration it is necessary to do that as I cannot
> convert all users at once - the domain you enter in the username field is
> then "authpoint" instead of something like "company.private". In the 2FA
> process, the OpenVPN client then opens a text window where you can enter a
> TOTP token or a "p" for a push request. The Backslash is no problem when
> not using 2FA, then the user auth succeeds.
> So it seems in the part for the extra control message handling handles
> backslashes incorrect.
>
> *Typed in Username: authpoint\UserN and corresponding password*
>
> Thu Mar 10 10:35:31 2022 VERIFY OK: depth=0, O=WatchGuard_Technologies,
> OU=Fireware, CN=Fireware SSLVPN Server
> Thu Mar 10 10:35:31 2022 Control Channel: TLSv1.2, cipher TLSv1.2
> ECDHE-RSA-CHACHA20-POLY1305, peer certificate: 2048 bit RSA, signature:
> RSA-SHA256
> Thu Mar 10 10:35:31 2022 [Fireware SSLVPN Server] Peer Connection
> Initiated with [AF_INET]1.2.3.4:443
> Thu Mar 10 10:35:32 2022 MANAGEMENT: >STATE:1646904932,GET_CONFIG,,
> Thu Mar 10 10:35:32 2022 SENT CONTROL [Fireware SSLVPN Server]:
> 'PUSH_REQUEST' (status=1)
> Thu Mar 10 10:35:32 2022 AUTH: Received control message:
> AUTH_FAILED,CRV1:R,E:1796:Yoirtuqeprtiqrew4==:*Type "p" to receive a push
> notification or type your one-time password*
>
>
> *(Typed in "p") *
> Thu Mar 10 10:35:32 2022 SIGUSR1[soft,auth-failure] received, process
> restarting
> Thu Mar 10 10:35:32 2022 MANAGEMENT:
> >STATE:1646904932,RECONNECTING,auth-failure,
> Thu Mar 10 10:35:32 2022 Restart pause, 5 second(s)
> *Thu Mar 10 10:35:40 2022 Previous command sent to management failed:
> ERROR: Options warning: Bad backslash ('\') usage in TCP:0: remember that
> backslashes are treated as shell-escapes and if you need to pass backslash
> characters as part of a Windows filename, you sho*
> Thu Mar 10 10:35:40 2022 MANAGEMENT: CMD 'username "Auth" "
> *authpoint\UserN*"'
> Thu Mar 10 10:35:40 2022 MANAGEMENT: CMD 'password [...]'
>
> This sounds like I need to escape the backslash, but if I do this the auth
> fails completely before the 2FA part comes into the picture.
> Other tricks like forward slashes or "@" do not help here as these are not
> understood by the auth backend in the firebox.
> When using the WatchGuard SSL VPN app this all works (and it has OpenVPN
> inside) but I would like to stick to the OpenVPN clients as all the
> users already have it and know how to handle it.
>

I missed this follow up on the devel list. Please see my reply to
openvpn-users. If @ doesnt work there is no easy fix short of patching the
GUI.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH master+release/2.5] error.c: use correct API to get error description on Windows

2022-02-21 Thread Selva Nair
Hi

On Mon, Feb 21, 2022 at 4:24 AM Lev Stipakov  wrote:

> We had a long discussion with ordex about this patch and came to the
> conclusion that error printing is currently broken on Windows and
> needs a proper fixing.
>
>
+1


> What we propose:
>
>  - M_ERRNO prints only C runtime errors on all platforms and should be
> only used with C runtime functions
>  - We add M_WINERR which uses GetLastError and FormatMessage to print
> Windows errors
>

While this would be a cleaner fix, it also requires extensive changes and
it is not always easy to decide where to use M_ERRNO and where to use
M_WINERR. E.g., without looking into the internals of platform.c one
doesn't know whether platform_open() uses _wopen() or CreateFile().

A possible option is to continue the use of M_ERRNO on WIndows as is
(except for socket errors), continue to use GetLastError() in x_msg(), but
if/when the latter if it returns zero, try errno and strerrror(). Not ideal
but less changes and easier and transparent to the user of msg(). That
said, I haven't checked whether GetLastError() returns zero or a valid and
correct error code for C runtime errors -- without which this approach wont
work.

 - We add M_SOCKERR, which is resolved into M_ERRNO on all platforms
> except Windows and on Windows it is M_WSAERR. We use WSAGetLastError
> and FormatMessage to print WSA errors. Socket functions use M_SOCKERR.
>

Sounds good.

BTW, there are a couple of uses of strerror() in check_status() (error.c)
missed by the original patch.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] pkcs11_openssl.c: check EVP_get_digestbyname() != NULL

2022-01-26 Thread selva . nair
From: Selva Nair 

Reported-by: Arne Schwabe 
Signed-off-by: Selva Nair 
---
 src/openvpn/pkcs11_openssl.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/openvpn/pkcs11_openssl.c b/src/openvpn/pkcs11_openssl.c
index a82b4b32..c4f88816 100644
--- a/src/openvpn/pkcs11_openssl.c
+++ b/src/openvpn/pkcs11_openssl.c
@@ -89,7 +89,14 @@ set_pss_params(CK_RSA_PKCS_PSS_PARAMS *pss_params, 
XKEY_SIGALG sigalg,
 pss_params->mgf = mdtypes[i].mgf_id;
 
 /* determine salt length */
-int mdsize = EVP_MD_size(EVP_get_digestbyname(sigalg.mdname));
+const EVP_MD *md = EVP_get_digestbyname(sigalg.mdname);
+if (!md)
+{
+msg(M_WARN, "WARN: set_pss_params: EVP_get_digestbyname returned NULL "
+"for mdname = <%s>", sigalg.mdname);
+goto cleanup;
+}
+int mdsize = EVP_MD_get_size(md);
 
 int saltlen = -1;
 if (!strcmp(sigalg.saltlen, "digest")) /* same as digest size */
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH 3/3] Support PSS signing using pkcs11-helper >= 1.28

2022-01-26 Thread Selva Nair
On Wed, Jan 26, 2022 at 6:50 AM Arne Schwabe  wrote:

> Am 25.01.22 um 03:51 schrieb selva.n...@gmail.com:
> > From: Selva Nair 
> >
> > - Call pkcs11h_certificate_signAny_ex() when available
> >so that the signature mechanism parameters can be pased.
> >(Required for RSA-PSS signature).
> >
> > Signed-off-by: Selva Nair 
> > ---
> >   src/openvpn/pkcs11_openssl.c | 123 +--
> >   1 file changed, 118 insertions(+), 5 deletions(-)
> >
> > diff --git a/src/openvpn/pkcs11_openssl.c b/src/openvpn/pkcs11_openssl.c
> > index 9cf46b2c..5d1a5de6 100644
> > --- a/src/openvpn/pkcs11_openssl.c
> > +++ b/src/openvpn/pkcs11_openssl.c
> > @@ -45,10 +45,112 @@
> >   #ifdef HAVE_XKEY_PROVIDER
> >   static XKEY_EXTERNAL_SIGN_fn xkey_pkcs11h_sign;
> >
> > +#if PKCS11H_VERSION > ((1<<16) | (27<<8)) /* version > 1.27 */
> > +
> > +/* Table linking OpenSSL digest NID with CKM and CKG constants in
> PKCS#11 */
> > +#define MD_TYPE(n) {NID_sha##n, CKM_SHA##n, CKG_MGF1_SHA##n}
> > +static const struct
> > +{
> > +   int nid;
> > +   unsigned long ckm_id;
> > +   unsigned long mgf_id;
> > +} mdtypes[] = {MD_TYPE(224), MD_TYPE(256), MD_TYPE(384), MD_TYPE(512),
> > +  {NID_sha1, CKM_SHA_1, CKG_MGF1_SHA1}, /* SHA_1 naming is
> an oddity */
> > +  {NID_undef, 0, 0}};
> > +
> > +/* From sigalg, derive parameters for pss signature and fill in
> pss_params.
> > + * Its of type CK_RSA_PKCS_PSS_PARAMS struct with three fields to be
> filled in:
> > + * {enum hashAlg, enum mgf, ulong sLen}
> > + * where hashAlg is CKM_SHA256 etc., mgf is CKG_MGF1_SHA256 etc.
> > + */
> > +static int
> > +set_pss_params(CK_RSA_PKCS_PSS_PARAMS *pss_params, XKEY_SIGALG sigalg,
> > +   pkcs11h_certificate_t cert)
> > +{
> > +int ret = 0;
> > +X509 *x509 = NULL;
> > +EVP_PKEY *pubkey = NULL;
> > +
> > +if ((x509 = pkcs11h_openssl_getX509(cert)) == NULL
> > +|| (pubkey = X509_get0_pubkey(x509)) == NULL)
> > +{
> > +msg(M_WARN, "PKCS#11: Unable get public key");
> > +goto cleanup;
> > +}
> > +
> > +/* map mdname to CKM and CKG constants for hash and mgf algorithms
> */
> > +int i = 0;
> > +int nid = OBJ_sn2nid(sigalg.mdname);
> > +while (mdtypes[i].nid != NID_undef && mdtypes[i].nid != nid)
> > +{
> > +i++;
> > +}
> > +pss_params->hashAlg = mdtypes[i].ckm_id;
> > +pss_params->mgf = mdtypes[i].mgf_id;
> > +
> > +/* determine salt length */
> > +int mdsize = EVP_MD_size(EVP_get_digestbyname(sigalg.mdname));
>
> This will break for newer hashes since it relies on nids but we have a
> fixed table anyway, it will break before that. But maybe we should bail
> out if we cannot find an entry in the translation table? Or is
> EVP_MD_size(NID_undef) well defined?
>

EVP_get_digestbyname(mdname) will return NULL if mdname is not recognized
(or has no NID etc), that when passed to EVP_MD_size(NULL) will trigger
an error and return -1 (based on OpenSSL source). So, yes, mdsize will be
wrong (-1), but we will catch it below where we check whether NID was found
in the table.

Not ideal, and you say, may be better to error out earlier if NID is
NID_undef or not in our table, or if EVP_get_digestbyname() returns NULL.

Selva
P.S. If the commit is not pushed yet, I can send a v2 for review, or follow
up with a fixup.
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v3] Allow PKCS#11 uri to be used as --cert and --key file names

2022-01-25 Thread Selva Nair
On Sun, Aug 15, 2021 at 6:26 PM  wrote:

> From: Selva Nair 
>
> v2 changes
>   - do not allow so-path embedded in cert and key uri
>   - add --pkcs11-engine option to optionally specify the
> engine and provider module to use
> v3: rebase to master
>
> If either --cert or --key is specified as a PKCS#11 uri, try to
> load the certificate and key from any accessible PKCS#11 device.
> This does not require linking with any pkcs11 library, but needs
> pkcs11 engine to be available on the target machine.
>
> In its simplest form, just have
>
> --cert 'pkcs11:id=%01'
>

I'm withdrawing this patch as it has no prospects going forward with
engines on their way out in
OpenSSL 3.0 and beyond. Withdrawing is also an honourable way out when no
one seems to care :)

That said, in the spirit of this patch, I think we should consider reusing
"--cert" and, optionally, "--key" options when newer ways of specifying the
certificate are introduced: like "--cert " instead of a new option
"--cryptoapi-cert " etc.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] Do not error when md_kt_size() is called with mdname="none"

2022-01-25 Thread Selva Nair
Hi,

On Tue, Jan 25, 2022 at 11:35 AM Antonio Quartulli  wrote:

> Hi,
>
> On 25/01/2022 17:30, Arne Schwabe wrote:
> > Am 25.01.22 um 17:27 schrieb Antonio Quartulli:
> >> Hi,
> >>
> >> On 21/01/2022 19:57, selva.n...@gmail.com wrote:
> >>> diff --git a/src/openvpn/crypto_openssl.c
> b/src/openvpn/crypto_openssl.c
> >>> index 35fb0052..b93c680a 100644
> >>> --- a/src/openvpn/crypto_openssl.c
> >>> +++ b/src/openvpn/crypto_openssl.c
> >>> @@ -1073,6 +1073,10 @@ md_kt_name(const char *mdname)
> >>>   unsigned char
> >>>   md_kt_size(const char *mdname)
> >>>   {
> >>> +if (!strcmp("none", mdname))
> >>
> >> Since we have it implemented, can we use streq() here?
> >>
> >> Cheers,
> >>
> >
> > streq is mainly used in option.c only, almost all other codes uses
> > strcmp insteads, so not really that strong of an argument.
>
> I thought options.c was part of this project too :-D
> To be honest, I think streq() is not really useful, but then we should
> either use it consistently or just drop it.
>
> I am in favour of dropping it because including options.h in other .c
> files can be quite a nightmare and you don't want that just to use streq().
>
> So I guess we can live with this patch, but should we put on the agenda
> wiping streq() for good?
>

"live with" ? When did strcmp() become a pariah?

Though strcmp()'s naming and return value are arguably not intuitive, we
are all used to it. That said, we have 472 uses of streq(), so let it be.
Just do not require that one should be preferred over the other.

Consistency is a good goal, but let's not be pedantic about it.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 1/3] xkey: Use a custom error level for debug messages

2022-01-24 Thread selva . nair
From: Selva Nair 

D_XKEY = loglev(6, 69, M_DEBUG) is defined and used for
all low level debug messages  from xkey_provider.c and
xkey_helper.c

As suggested by Arne Schwabe 

Signed-off-by: Selva Nair 
---
 src/openvpn/errlevel.h  |  1 +
 src/openvpn/xkey_helper.c   |  8 +--
 src/openvpn/xkey_provider.c | 98 ++---
 3 files changed, 54 insertions(+), 53 deletions(-)

diff --git a/src/openvpn/errlevel.h b/src/openvpn/errlevel.h
index 602e48a8..94c6c282 100644
--- a/src/openvpn/errlevel.h
+++ b/src/openvpn/errlevel.h
@@ -113,6 +113,7 @@
 #define D_TUN_RW LOGLEV(6, 69, M_DEBUG)  /* show TUN/TAP 
reads/writes */
 #define D_TAP_WIN_DEBUG  LOGLEV(6, 69, M_DEBUG)  /* show TAP-Windows 
driver debug info */
 #define D_CLIENT_NAT LOGLEV(6, 69, M_DEBUG)  /* show client NAT debug 
info */
+#define D_XKEY   LOGLEV(6, 69, M_DEBUG)  /* show xkey-provider 
debug info */
 
 #define D_SHOW_KEYS  LOGLEV(7, 70, M_DEBUG)  /* show data channel 
encryption keys */
 #define D_SHOW_KEY_SOURCELOGLEV(7, 70, M_DEBUG)  /* show data channel key 
source entropy */
diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c
index c667f7be..582bec5d 100644
--- a/src/openvpn/xkey_helper.c
+++ b/src/openvpn/xkey_helper.c
@@ -65,7 +65,7 @@ int
 xkey_digest(const unsigned char *src, size_t srclen, unsigned char *buf,
 size_t *buflen, const char *mdname)
 {
-dmsg(D_LOW, "In xkey_digest");
+dmsg(D_XKEY, "In xkey_digest");
 EVP_MD *md = EVP_MD_fetch(NULL, mdname, NULL); /* from default context */
 if (!md)
 {
@@ -163,7 +163,7 @@ int
 xkey_management_sign(void *unused, unsigned char *sig, size_t *siglen,
  const unsigned char *tbs, size_t tbslen, XKEY_SIGALG alg)
 {
-dmsg(D_LOW, "In xkey_management_sign with keytype = %s, op = %s",
+dmsg(D_XKEY, "In xkey_management_sign with keytype = %s, op = %s",
  alg.keytype, alg.op);
 
 (void) unused;
@@ -180,7 +180,7 @@ xkey_management_sign(void *unused, unsigned char *sig, 
size_t *siglen,
 /* if management client cannot do digest -- we do it here */
 if (!strcmp(alg.op, "DigestSign") && !(flags & MF_EXTERNAL_KEY_DIGEST))
 {
-dmsg(D_LOW, "xkey_management_sign: computing digest");
+dmsg(D_XKEY, "xkey_management_sign: computing digest");
 if (xkey_digest(tbs, tbslen, buf, , alg.mdname))
 {
 tbs = buf;
@@ -379,7 +379,7 @@ encode_pkcs1(unsigned char *enc, size_t *enc_len, const 
char *mdname,
 /* combine header and digest */
 memcpy(enc, di->header, di->sz);
 memcpy(enc + di->sz, tbs, tbslen);
-dmsg(D_LOW, "encode_pkcs1: digest length = %d encoded length = %d",
+dmsg(D_XKEY, "encode_pkcs1: digest length = %d encoded length = %d",
  (int) tbslen, (int) out_len);
 ret = true;
 }
diff --git a/src/openvpn/xkey_provider.c b/src/openvpn/xkey_provider.c
index c2d560c5..9a02ed13 100644
--- a/src/openvpn/xkey_provider.c
+++ b/src/openvpn/xkey_provider.c
@@ -146,7 +146,7 @@ keymgmt_import_helper(XKEY_KEYDATA *key, const OSSL_PARAM 
params[]);
 static XKEY_KEYDATA *
 keydata_new()
 {
-xkey_dmsg(D_LOW, "entry");
+xkey_dmsg(D_XKEY, "entry");
 
 XKEY_KEYDATA *key = OPENSSL_zalloc(sizeof(*key));
 if (!key)
@@ -160,7 +160,7 @@ keydata_new()
 static void
 keydata_free(XKEY_KEYDATA *key)
 {
-xkey_dmsg(D_LOW, "entry");
+xkey_dmsg(D_XKEY, "entry");
 
 if (!key || key->refcount-- > 0) /* free when refcount goes to zero */
 {
@@ -181,7 +181,7 @@ keydata_free(XKEY_KEYDATA *key)
 static void *
 keymgmt_new(void *provctx)
 {
-xkey_dmsg(D_LOW, "entry");
+xkey_dmsg(D_XKEY, "entry");
 
 XKEY_KEYDATA *key = keydata_new();
 if (key)
@@ -195,7 +195,7 @@ keymgmt_new(void *provctx)
 static void *
 keymgmt_load(const void *reference, size_t reference_sz)
 {
-xkey_dmsg(D_LOW, "entry");
+xkey_dmsg(D_XKEY, "entry");
 
 return NULL;
 }
@@ -235,7 +235,7 @@ keymgmt_load(const void *reference, size_t reference_sz)
 static int
 keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[], const 
char *name)
 {
-xkey_dmsg(D_LOW, "entry");
+xkey_dmsg(D_XKEY, "entry");
 
 XKEY_KEYDATA *key = keydata;
 ASSERT(key);
@@ -252,11 +252,11 @@ keymgmt_import(void *keydata, int selection, const 
OSSL_PARAM params[], const ch
 if (p && p->data_type == OSSL_PARAM_UTF8_STRING)
 {
 key->origin = EXTERNAL_KEY;
-xkey_dmsg(D_LOW, "importing external key");
+xkey_dmsg(D_XKEY, "importing external key");
 return keymgmt_import_helper(key, params);
 }
 
-xkey_dmsg(D_LOW, "importing native

[Openvpn-devel] [PATCH 2/3] Fix max saltlen calculation in cryptoapi.c

2022-01-24 Thread selva . nair
From: Selva Nair 

(nbits - 1)/8 should have been rounded up. Fix and move it to
an inlined function for reuse in pkcs11_openssl.c (used in the
next commit).

Note: The error is not triggered in normal use as OpenSSL
always seems to use saltlen="digest" for signing.

Signed-off-by: Selva Nair 
---
 src/openvpn/cryptoapi.c   |  2 +-
 src/openvpn/xkey_common.h | 14 ++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/openvpn/cryptoapi.c b/src/openvpn/cryptoapi.c
index 8e0ceba7..56cab962 100644
--- a/src/openvpn/cryptoapi.c
+++ b/src/openvpn/cryptoapi.c
@@ -843,7 +843,7 @@ xkey_cng_rsa_sign(CAPI_DATA *cd, unsigned char *sig, size_t 
*siglen, const unsig
 int saltlen = tbslen; /* digest size by default */
 if (!strcmp(sigalg.saltlen, "max"))
 {
-saltlen = (EVP_PKEY_bits(cd->pubkey) - 1)/8 - tbslen - 2;
+saltlen = xkey_max_saltlen(EVP_PKEY_bits(cd->pubkey), tbslen);
 if (saltlen < 0)
 {
 msg(M_NONFATAL, "Error in cryptoapicert: invalid salt length 
(%d)", saltlen);
diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h
index 75ca5011..1e51e672 100644
--- a/src/openvpn/xkey_common.h
+++ b/src/openvpn/xkey_common.h
@@ -153,6 +153,20 @@ xkey_load_generic_key(OSSL_LIB_CTX *libctx, void *handle, 
EVP_PKEY *pubkey,
 
 extern OSSL_LIB_CTX *tls_libctx; /* Global */
 
+/**
+ * Maximum salt length for PSS signature.
+ *
+ * @param modBitsNumber of bits in RSA modulus
+ * @param hLen   Length of digest to be signed
+ * @returns the maximum allowed salt length. Caller must check it's not < 0.
+ */
+static inline int
+xkey_max_saltlen(int modBits, int hLen)
+{
+int emLen = (modBits - 1 + 7)/8; /* ceil((modBits - 1)/8) */
+
+return emLen - hLen - 2;
+}
 #endif /* HAVE_XKEY_PROVIDER */
 
 #endif /* XKEY_COMMON_H_ */
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 3/3] Support PSS signing using pkcs11-helper >= 1.28

2022-01-24 Thread selva . nair
From: Selva Nair 

- Call pkcs11h_certificate_signAny_ex() when available
  so that the signature mechanism parameters can be pased.
  (Required for RSA-PSS signature).

Signed-off-by: Selva Nair 
---
 src/openvpn/pkcs11_openssl.c | 123 +--
 1 file changed, 118 insertions(+), 5 deletions(-)

diff --git a/src/openvpn/pkcs11_openssl.c b/src/openvpn/pkcs11_openssl.c
index 9cf46b2c..5d1a5de6 100644
--- a/src/openvpn/pkcs11_openssl.c
+++ b/src/openvpn/pkcs11_openssl.c
@@ -45,10 +45,112 @@
 #ifdef HAVE_XKEY_PROVIDER
 static XKEY_EXTERNAL_SIGN_fn xkey_pkcs11h_sign;
 
+#if PKCS11H_VERSION > ((1<<16) | (27<<8)) /* version > 1.27 */
+
+/* Table linking OpenSSL digest NID with CKM and CKG constants in PKCS#11 */
+#define MD_TYPE(n) {NID_sha##n, CKM_SHA##n, CKG_MGF1_SHA##n}
+static const struct
+{
+   int nid;
+   unsigned long ckm_id;
+   unsigned long mgf_id;
+} mdtypes[] = {MD_TYPE(224), MD_TYPE(256), MD_TYPE(384), MD_TYPE(512),
+  {NID_sha1, CKM_SHA_1, CKG_MGF1_SHA1}, /* SHA_1 naming is an 
oddity */
+  {NID_undef, 0, 0}};
+
+/* From sigalg, derive parameters for pss signature and fill in  pss_params.
+ * Its of type CK_RSA_PKCS_PSS_PARAMS struct with three fields to be filled in:
+ * {enum hashAlg, enum mgf, ulong sLen}
+ * where hashAlg is CKM_SHA256 etc., mgf is CKG_MGF1_SHA256 etc.
+ */
+static int
+set_pss_params(CK_RSA_PKCS_PSS_PARAMS *pss_params, XKEY_SIGALG sigalg,
+   pkcs11h_certificate_t cert)
+{
+int ret = 0;
+X509 *x509 = NULL;
+EVP_PKEY *pubkey = NULL;
+
+if ((x509 = pkcs11h_openssl_getX509(cert)) == NULL
+|| (pubkey = X509_get0_pubkey(x509)) == NULL)
+{
+msg(M_WARN, "PKCS#11: Unable get public key");
+goto cleanup;
+}
+
+/* map mdname to CKM and CKG constants for hash and mgf algorithms */
+int i = 0;
+int nid = OBJ_sn2nid(sigalg.mdname);
+while (mdtypes[i].nid != NID_undef && mdtypes[i].nid != nid)
+{
+i++;
+}
+pss_params->hashAlg = mdtypes[i].ckm_id;
+pss_params->mgf = mdtypes[i].mgf_id;
+
+/* determine salt length */
+int mdsize = EVP_MD_size(EVP_get_digestbyname(sigalg.mdname));
+
+int saltlen = -1;
+if (!strcmp(sigalg.saltlen, "digest")) /* same as digest size */
+{
+saltlen = mdsize;
+}
+else if (!strcmp(sigalg.saltlen, "max")) /* maximum possible value */
+{
+saltlen = xkey_max_saltlen(EVP_PKEY_get_bits(pubkey), mdsize);
+}
+
+if (saltlen < 0 || pss_params->hashAlg == 0)
+{
+msg(M_WARN, "WARN: invalid RSA_PKCS1_PSS parameters: saltlen = <%s> "
+"mdname = <%s>.", sigalg.saltlen, sigalg.mdname);
+goto cleanup;
+}
+pss_params->sLen = (unsigned long) saltlen; /* saltlen >= 0 at this point 
*/
+
+msg(D_XKEY, "set_pss_params: sLen = %lu, hashAlg = %lu, mgf = %lu",
+pss_params->sLen, pss_params->hashAlg, pss_params->mgf);
+
+ret = 1;
+
+cleanup:
+if (x509)
+{
+X509_free(x509);
+}
+return ret;
+}
+
+#else
+
+/* Make set_pss_params a no-op that always succeeds */
+#define set_pss_params(...) (1)
+
+/* Use a wrapper for pkcs11h_certificate_signAny_ex() for versions < 1.28
+ * where its not available.
+ * We just call pkcs11h_certificate_signAny() unless the padding
+ * is PSS in which case we return an error.
+ */
+static CK_RV
+pkcs11h_certificate_signAny_ex(const pkcs11h_certificate_t cert,
+const CK_MECHANISM *mech, const unsigned char *tbs,
+size_t tbslen, unsigned char *sig, size_t *siglen)
+{
+if (mech->mechanism == CKM_RSA_PKCS_PSS)
+{
+msg(M_NONFATAL, "PKCS#11: Error: PSS padding is not supported by "
+"this version of pkcs11-helper library.");
+return CKR_MECHANISM_INVALID;
+}
+return pkcs11h_certificate_signAny(cert, mech->mechanism, tbs, tbslen, 
sig, siglen);
+}
+#endif /* PKCS11H_VERSION > 1.27 */
+
 /**
  * Sign op called from xkey provider
  *
- * We support ECDSA, RSA_NO_PADDING, RSA_PKCS1_PADDING
+ * We support ECDSA, RSA_NO_PADDING, RSA_PKCS1_PADDING, RSA_PKCS_PSS_PADDING
  */
 static int
 xkey_pkcs11h_sign(void *handle, unsigned char *sig,
@@ -62,7 +164,7 @@ xkey_pkcs11h_sign(void *handle, unsigned char *sig,
 
 if (!strcmp(sigalg.op, "DigestSign"))
 {
-dmsg(D_LOW, "xkey_pkcs11h_sign: computing digest");
+msg(D_XKEY, "xkey_pkcs11h_sign: computing digest");
 if (xkey_digest(tbs, tbslen, buf, , sigalg.mdname))
 {
 tbs = buf;
@@ -77,18 +179,29 @@ xkey_pkcs11h_sign(void *handle, unsigned char *sig,
 
 if (!strcmp(sigalg.keytype, "EC"))
 {
+msg(D_XKEY, "xkey_pkcs11h_sign: signing with EC key");
 mech.mechanism = CKM_ECDSA;
  

Re: [Openvpn-devel] [PATCH 1/2] xkey: fix msvc build

2022-01-24 Thread Selva Nair
On Mon, Jan 24, 2022 at 2:22 PM Lev Stipakov  wrote:

> From: Lev Stipakov 
>
>  - use sizeof(void *) since msvc doesn't support sizeof of function ptr
>

This is not just an msvc problem, but signals a bigger issue it seems. In
retrospect, passing function pointers  pickled this was probably a bad
design decision on my part though we are forced by OpenSSL 3's design of
using OSSL_PARAMs to pass data to providers.

For now, The proposed fix (i.e., to use void*) looks okay to me especially
since its handled like a normal pointer during key import. But we may have
to find a better way for passing these function pointers if this comes back
to bite us.


>
>  - use XKEY_PROV_PROPS macro instead of props since msvc
>   requires constant expression in aggregate initializers
>

Makes sense.


> Signed-off-by: Lev Stipakov 
> ---
>  src/openvpn/xkey_helper.c   |  4 ++--
>  src/openvpn/xkey_provider.c | 13 +
>  2 files changed, 7 insertions(+), 10 deletions(-)
>
> diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c
> index c667f7be..50231335 100644
> --- a/src/openvpn/xkey_helper.c
> +++ b/src/openvpn/xkey_helper.c
> @@ -125,8 +125,8 @@ xkey_load_generic_key(OSSL_LIB_CTX *libctx, void
> *handle, EVP_PKEY *pubkey,
>  {"xkey-origin", OSSL_PARAM_UTF8_STRING, (char *) origin, 0, 0},
>  {"pubkey", OSSL_PARAM_OCTET_STRING, , sizeof(pubkey), 0},
>  {"handle", OSSL_PARAM_OCTET_PTR, , sizeof(handle), 0},
> -{"sign_op", OSSL_PARAM_OCTET_PTR, (void **) _op,
> sizeof(sign_op), 0},
> -{"free_op", OSSL_PARAM_OCTET_PTR, (void **) _op,
> sizeof(free_op), 0},
> +{"sign_op", OSSL_PARAM_OCTET_PTR, (void **) _op, sizeof(void
> *), 0},
> +{"free_op", OSSL_PARAM_OCTET_PTR, (void **) _op, sizeof(void
> *), 0},
>  {NULL, 0, NULL, 0, 0}};
>
>  /* Do not use EVP_PKEY_new_from_pkey as that will take keymgmt from
> pubkey */
> diff --git a/src/openvpn/xkey_provider.c b/src/openvpn/xkey_provider.c
> index c2d560c5..115b9931 100644
> --- a/src/openvpn/xkey_provider.c
> +++ b/src/openvpn/xkey_provider.c
> @@ -44,9 +44,6 @@
>  #include 
>  #include 
>
> -/* propq set all on all ops we implement */
> -static const char *const props = XKEY_PROV_PROPS;
> -
>  /* A descriptive name */
>  static const char *provname = "OpenVPN External Key Provider";
>
> @@ -592,9 +589,9 @@ static const OSSL_DISPATCH ec_keymgmt_functions[] = {
>  };
>
>  const OSSL_ALGORITHM keymgmts[] = {
> -{"RSA:rsaEncryption", props, rsa_keymgmt_functions, "OpenVPN xkey RSA
> Key Manager"},
> -{"RSA-PSS:RSASSA-PSS", props, rsa_keymgmt_functions, "OpenVPN xkey
> RSA-PSS Key Manager"},
> -{"EC:id-ecPublicKey", props, ec_keymgmt_functions, "OpenVPN xkey EC
> Key Manager"},
> +{"RSA:rsaEncryption", XKEY_PROV_PROPS, rsa_keymgmt_functions,
> "OpenVPN xkey RSA Key Manager"},
> +{"RSA-PSS:RSASSA-PSS", XKEY_PROV_PROPS, rsa_keymgmt_functions,
> "OpenVPN xkey RSA-PSS Key Manager"},
> +{"EC:id-ecPublicKey", XKEY_PROV_PROPS, ec_keymgmt_functions, "OpenVPN
> xkey EC Key Manager"},
>  {NULL, NULL, NULL, NULL}
>  };
>
> @@ -1074,8 +1071,8 @@ static const OSSL_DISPATCH signature_functions[] = {
>  };
>
>  const OSSL_ALGORITHM signatures[] = {
> -{"RSA:rsaEncryption", props, signature_functions, "OpenVPN xkey RSA
> Signature"},
> -{"ECDSA", props, signature_functions, "OpenVPN xkey ECDSA Signature"},
> +{"RSA:rsaEncryption", XKEY_PROV_PROPS, signature_functions, "OpenVPN
> xkey RSA Signature"},
> +{"ECDSA", XKEY_PROV_PROPS, signature_functions, "OpenVPN xkey ECDSA
> Signature"},
>  {NULL, NULL, NULL, NULL}
>  };


Acked-by: Selva Nair 
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] msvc: switch to openssl3

2022-01-24 Thread Selva Nair
Hi

On Mon, Jan 24, 2022 at 1:56 PM Lev Stipakov  wrote:

> Hi,
>
> > A whole patch in the commit message is not very helpful and makes it
> hard to read. Why not include this patch + the original, and apply the
> patch during build?
> >
> > Or just add a pointer to the original file in the changed file so that
> it could be diff-ed against if need be,
>
> Yeah, I was not sure what is the best way to indicate difference
> between this one and original one, so I added it to commit message.
> Not sure what do you mean by "apply the patch during build" - you can
> have patches for port sources but I don't think you can patch the port
> script.


> Like you proposed I could add a comment to the patched file which
> points to original one.
>

As mentioned in my response to the GUI PR, I just can't bring myself to
like this idea of matching vcpkg ports in OpenVPN core and GUI and the need
to keep them in sync, keep them updated etc. Feels like a  wrong approach
though I do not know enough to suggest  a better way.


>
> > These changes look sane though I think this should be a separate commit.
>
> I could do that, but then commit without those changes will break the
> build.
>

Your fix to the xkey patch set is actually a generic one, not just a
work-around for msvc. It could be applied first before fixing the msvc
build.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] msvc: switch to openssl3

2022-01-24 Thread Selva Nair
Hi

On Mon, Jan 24, 2022 at 4:47 AM Lev Stipakov  wrote:

> From: Lev Stipakov 
>
>  - add openssl3 port from
> https://github.com/microsoft/vcpkg/pull/20428/files
> with small changes:
>
> --- portfile.cmake.orig 2022-01-24 11:04:44.914467900 +0200
> +++ portfile.cmake  2022-01-24 11:02:46.066088800 +0200
> @@ -5,8 +5,8 @@
>  vcpkg_from_github(
>  OUT_SOURCE_PATH SOURCE_PATH
>  REPO openssl/openssl
> -REF openssl-3.0.0
> -SHA512
>
> 50b4fefa3e5a3359e7b06bfbc4ecc525ef9d76e13d087aa8e2d29880f08f74cc9d0c76b9bf1895c118def2bb0e4db0095e799a752b64b60721a423bd2cf989da
> +REF openssl-3.0.1
> +SHA512
>
> 7f303769a3a796b88478399d42aa2a9a70dc74f62c975bbb93e8903e3bb8e25f16ecfc436186c2d4aa7383302c73ad1dd8ac4fccaa589062bbce6059d6073f18
>  )
>
>  if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic")
> @@ -114,13 +114,13 @@
>  if(VCPKG_TARGET_IS_UWP OR VCPKG_TARGET_IS_WINDOWS)
>  message(STATUS "Building ${TARGET_TRIPLET}-dbg")
>  vcpkg_execute_required_process(
> -COMMAND ${JOM} /K /J ${VCPKG_CONCURRENCY} /F makefile
> install_dev
> +COMMAND ${JOM} /K /J ${VCPKG_CONCURRENCY} /F makefile
> install_dev install_runtime
>  WORKING_DIRECTORY
> "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-dbg"
>  LOGNAME install-${TARGET_TRIPLET}-dbg
>  )
>  message(STATUS "Building ${TARGET_TRIPLET}-rel")
>  vcpkg_execute_required_process(
> -COMMAND ${JOM} /K /J ${VCPKG_CONCURRENCY} /F makefile
> install_dev
> +COMMAND ${JOM} /K /J ${VCPKG_CONCURRENCY} /F makefile
> install_dev install_runtime
>  WORKING_DIRECTORY
> "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel"
>  LOGNAME install-${TARGET_TRIPLET}-rel
>  )
> @@ -129,13 +129,13 @@
>  else()
>  message(STATUS "Building ${TARGET_TRIPLET}-dbg")
>  vcpkg_execute_required_process(
> -COMMAND ${MAKE} -j ${VCPKG_CONCURRENCY} install_dev
> +COMMAND ${MAKE} -j ${VCPKG_CONCURRENCY} install_dev
> install_runtime
>  WORKING_DIRECTORY
> "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-dbg"
>  LOGNAME install-${TARGET_TRIPLET}-dbg
>  )
>  message(STATUS "Building ${TARGET_TRIPLET}-rel")
>  vcpkg_execute_required_process(
> -COMMAND ${MAKE} -j ${VCPKG_CONCURRENCY} install_dev
> +COMMAND ${MAKE} -j ${VCPKG_CONCURRENCY} install_dev
> install_runtime
>  WORKING_DIRECTORY
> "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel"
>  LOGNAME install-${TARGET_TRIPLET}-rel
>  )
> @@ -161,6 +161,17 @@
>
>  endif()
>
> +if(VCPKG_TARGET_IS_WINDOWS)
> +file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/tools/openssl/")
> +file(RENAME "${CURRENT_PACKAGES_DIR}/bin/openssl.exe"
> "${CURRENT_PACKAGES_DIR}/tools/openssl/openssl.exe")
> +
> +file(REMOVE
> +"${CURRENT_PACKAGES_DIR}/debug/bin/openssl.exe"
> +)
> +endif()
> +
> +vcpkg_copy_tool_dependencies("${CURRENT_PACKAGES_DIR}/tools/openssl")
> +
>  if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic")
>  file(REMOVE "${CURRENT_PACKAGES_DIR}/debug/lib/libcrypto.a"
>  "${CURRENT_PACKAGES_DIR}/debug/lib/libssl.a"
> @@ -184,4 +195,4 @@
>  )
>  file(INSTALL "${CURRENT_PORT_DIR}/usage"
>   DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}"
> -)
> \ No newline at end of file
> +)
>

A whole patch in the commit message is not very helpful and makes it hard
to read. Why not include this patch + the original, and apply the patch
during build?

Or just add a pointer to the original file in the changed file so that it
could be diff-ed against if need be,


>  - use sizeof(void *) since msvc doesn't support sizeof of function ptr


>  - use XKEY_PROV_PROPS macro instead of props since msvc
>   requires constant expression in aggregate initializers
>

These changes look sane though I think this should be a separate commit.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v3] crypto: Fix OPENSSL_FIPS enabled builds

2022-01-21 Thread Selva Nair
Hi

On Fri, Jan 21, 2022 at 12:10 PM Gert Doering  wrote:

> Hi,
>
> On Wed, Jan 19, 2022 at 07:21:26PM +0100, David Sommerseth wrote:
> > index 5626e2b6..eb0b1254 100644
> > --- a/src/openvpn/crypto.c
> > +++ b/src/openvpn/crypto.c
> > @@ -34,6 +34,7 @@
> >  #include "error.h"
> >  #include "integer.h"
> >  #include "platform.h"
> > +#include "openssl_compat.h"
> >
> >  #include "memdbg.h"
>
> This breaks compilation for mbedtls builds, depending on which version
> of OpenSSL happens to be installed on the system (if any).
>
> In this particular case, mbedtls build with a system openssl of 0.9.8,
> it blows up with
>
> In file included from crypto.c:37:
> openssl_compat.h: In function 'SSL_CTX_get_min_proto_version':
> openssl_compat.h:635: error: 'SSL_OP_NO_TLSv1_1' undeclared
> (first use in this
>
> (and more of this)
>
> which is unsurprising - it's not supposed to pull in these headers
> in the first place.
>

Looking back at it, the patch and the problem it's trying to solve are both
misplaced in crypto.c. That file should be ssl-lib agnostic and openssl
related bits should go to crypto_openssl.c...

I think we need to remove that OPENSSL_FIPS clause and think of providing
that extra info somewhere else if possible.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] Do not error when md_kt_size() is called with mdname="none"

2022-01-21 Thread selva . nair
From: Selva Nair 

An easy way to trigger this error is to run an otherwise working setup
(at say verb = 4) with increased verbosity of verb >= 7 and using a GCM 
cipher (e.g., AES-256-GCM). It will cause a fatal exit while printing the 
cipher and hmac in key2_print().

Signed-off-by: Selva Nair 
---
Its actually md_get("none") called by md_kt_size("none") that
causes the error and I'm not entirely sure whether we should
instead make md_get("none") to return NULL. But that would
require all its callers to check for NULL.

 src/openvpn/crypto_openssl.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index 35fb0052..b93c680a 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -1073,6 +1073,10 @@ md_kt_name(const char *mdname)
 unsigned char
 md_kt_size(const char *mdname)
 {
+if (!strcmp("none", mdname))
+{
+return 0;
+}
 evp_md_type *kt = md_get(mdname);
 unsigned char size =  (unsigned char)EVP_MD_size(kt);
 EVP_MD_free(kt);
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v3] tun: remove tun_finalize()

2022-01-20 Thread Selva Nair
ap *tt, struct buffer
> *buf)
>  }
>
>  int
> -tun_finalize(
> -HANDLE h,
> -struct overlapped_io *io,
> -struct buffer *buf)
> +tun_write_win32(struct tuntap *tt, struct buffer *buf)
>  {
> -int ret = -1;
> -BOOL status;
> -
> -switch (io->iostate)
> +int err = 0;
> +int status = 0;
> +if (overlapped_io_active(>writes))
>  {
> -case IOSTATE_QUEUED:
> -status = GetOverlappedResult(
> -h,
> ->overlapped,
> ->size,
> -FALSE
> -);
> -if (status)
> -{
> -/* successful return for a queued operation */
> -if (buf)
> -{
> -*buf = io->buf;
> -}
> -ret = io->size;
> -io->iostate = IOSTATE_INITIAL;
> -ASSERT(ResetEvent(io->overlapped.hEvent));
> -dmsg(D_WIN32_IO, "WIN32 I/O: TAP Completion success
> [%d]", ret);
> -}
> -else
> -{
> -/* error during a queued operation */
> -ret = -1;
> -if (GetLastError() != ERROR_IO_INCOMPLETE)
> -{
> -/* if no error (i.e. just not finished yet),
> - * then DON'T execute this code */
> -io->iostate = IOSTATE_INITIAL;
> -ASSERT(ResetEvent(io->overlapped.hEvent));
> -msg(D_WIN32_IO | M_ERRNO, "WIN32 I/O: TAP Completion
> error");
> -}
> -}
> -break;
> -
> -case IOSTATE_IMMEDIATE_RETURN:
> -io->iostate = IOSTATE_INITIAL;
> -ASSERT(ResetEvent(io->overlapped.hEvent));
> -if (io->status)
> -{
> -/* error return for a non-queued operation */
> -SetLastError(io->status);
> -ret = -1;
> -msg(D_WIN32_IO | M_ERRNO, "WIN32 I/O: TAP Completion
> non-queued error");
> -}
> -else
> -{
> -/* successful return for a non-queued operation */
> -if (buf)
> -{
> -*buf = io->buf;
> -}
> -ret = io->size;
> -dmsg(D_WIN32_IO, "WIN32 I/O: TAP Completion non-queued
> success [%d]", ret);
> -}
> -break;
> -
> -case IOSTATE_INITIAL: /* were we called without proper queueing?
> */
> -SetLastError(ERROR_INVALID_FUNCTION);
> -ret = -1;
> -dmsg(D_WIN32_IO, "WIN32 I/O: TAP Completion BAD STATE");
> -break;
> -
> -default:
> -ASSERT(0);
> +sockethandle_t sh = { .is_handle = true, .h = tt->hand };
> +status = sockethandle_finalize(sh, >writes, NULL, NULL);
> +if (status < 0)
> +{
> +err = GetLastError();
> +}
>  }
> -
> -if (buf)
> +tun_write_queue(tt, buf);
> +if (status < 0)
>  {
> -buf->len = ret;
> +SetLastError(err);
> +return status;
> +}
> +else
> +{
> +return BLEN(buf);
>  }
> -return ret;
>  }
>
>  static const struct device_instance_id_interface *
> diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h
> index d4657537..a6661be0 100644
> --- a/src/openvpn/tun.h
> +++ b/src/openvpn/tun.h
> @@ -437,8 +437,6 @@ int tun_read_queue(struct tuntap *tt, int maxsize);
>
>  int tun_write_queue(struct tuntap *tt, struct buffer *buf);
>
> -int tun_finalize(HANDLE h, struct overlapped_io *io, struct buffer *buf);
> -
>  static inline bool
>  tuntap_stop(int status)
>  {
> @@ -466,36 +464,8 @@ tuntap_abort(int status)
>  return false;
>  }
>
> -static inline int
> -tun_write_win32(struct tuntap *tt, struct buffer *buf)
> -{
> -int err = 0;
> -int status = 0;
> -if (overlapped_io_active(>writes))
> -{
> -status = tun_finalize(tt->hand, >writes, NULL);
> -if (status < 0)
> -{
> -err = GetLastError();
> -}
> -}
> -tun_write_queue(tt, buf);
> -if (status < 0)
> -{
> -SetLastError(err);
> -return status;
> -}
> -else
> -{
> -return BLEN(buf);
> -}
> -}
> -
> -static inline int
> -read_tun_buffered(struct tuntap *tt, struct buffer *buf)
> -{
> -return tun_finalize(tt->hand, >reads, buf);
> -}
> +int
> +tun_write_win32(struct tuntap *tt, struct buffer *buf);
>

Antonio wanted this to be in one line though we are not terribly consistent
about this.


>  static inline ULONG
>  wintun_ring_packet_align(ULONG size)
>

In spite of those nits meant to annoy the author, I think this looks good.

Acked-by: Selva Nair 
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH applied] Re: Enable signing via provider for management-external-key

2022-01-20 Thread Selva Nair
Hi,

On Thu, Jan 20, 2022 at 10:18 AM Gert Doering  wrote:

> Compile and client tested on 1.1.1 and 3.0.1.
>
> Glancing at the code related to management_external_key() does
> not make me very happy... too many build time variants.


"Happiness" is never a word that comes to mind while reading OpenVPN code :)
...

Even at our snail's pace, 2.7 may be out before we can break free of
OpenSSL 1, LibreSSL xyz etc. An option may be to require OpenSSL 3+ or
similar for external keys, or at least for management-external-key.

That feature is really used by only a few platforms (only Android for
now?). Although it's a nifty option that could potentially be leveraged to
remove pkcs11-helper, CNG etc out of OpenVPN core.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] Fix a potential memory leak in tls_ctx_use_management_external_key

2022-01-20 Thread selva . nair
From: Selva Nair 

As pointed out by Gert Doering 

Signed-off-by: Selva Nair 
---
To be applied after 06/18 of xkey patchset

 src/openvpn/ssl_openssl.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index b48845eb..3f8c3091 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -1493,6 +1493,7 @@ tls_ctx_use_management_external_key(struct tls_root_ctx 
*ctx)
 if (!privkey
 || !SSL_CTX_use_PrivateKey(ctx->ctx, privkey))
 {
+EVP_PKEY_free(privkey);
 goto cleanup;
 }
 EVP_PKEY_free(privkey);
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH v4 16+17/18] Add a unit test for external key provider

2022-01-20 Thread selva . nair
From: Selva Nair 

Tests:
- Check SIGNATURE and KEYMGMT methods can be fetched
  from the provider
- Load sample RSA and EC keys as management-external-key
  and check that their sign callbacks are correctly exercised:
  with and without digest support mocked in the client
  capability flag.
 -Test generic key load and signature

v4: 16/18 and 17/18 of v3 squashed into one patch

Signed-off-by: Selva Nair 
---
 tests/unit_tests/openvpn/Makefile.am |  16 +
 tests/unit_tests/openvpn/test_provider.c | 403 +++
 2 files changed, 419 insertions(+)
 create mode 100644 tests/unit_tests/openvpn/test_provider.c

diff --git a/tests/unit_tests/openvpn/Makefile.am 
b/tests/unit_tests/openvpn/Makefile.am
index 44b77cc5..6b5c94ab 100644
--- a/tests/unit_tests/openvpn/Makefile.am
+++ b/tests/unit_tests/openvpn/Makefile.am
@@ -11,6 +11,8 @@ if HAVE_LD_WRAP_SUPPORT
 test_binaries += tls_crypt_testdriver
 endif
 
+test_binaries += provider_testdriver
+
 TESTS = $(test_binaries)
 check_PROGRAMS = $(test_binaries)
 
@@ -95,6 +97,20 @@ networking_testdriver_SOURCES = test_networking.c mock_msg.c 
\
$(openvpn_srcdir)/platform.c
 endif
 
+provider_testdriver_CFLAGS  = @TEST_CFLAGS@ \
+   -I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \
+   $(OPTIONAL_CRYPTO_CFLAGS)
+provider_testdriver_LDFLAGS = @TEST_LDFLAGS@ \
+   $(OPTIONAL_CRYPTO_LIBS)
+
+provider_testdriver_SOURCES = test_provider.c mock_msg.c \
+   $(openvpn_srcdir)/xkey_helper.c \
+   $(openvpn_srcdir)/xkey_provider.c \
+   $(openvpn_srcdir)/buffer.c \
+   $(openvpn_srcdir)/base64.c \
+   mock_get_random.c \
+   $(openvpn_srcdir)/platform.c
+
 auth_token_testdriver_CFLAGS  = @TEST_CFLAGS@ \
-I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \
$(OPTIONAL_CRYPTO_CFLAGS)
diff --git a/tests/unit_tests/openvpn/test_provider.c 
b/tests/unit_tests/openvpn/test_provider.c
new file mode 100644
index ..0182b3b4
--- /dev/null
+++ b/tests/unit_tests/openvpn/test_provider.c
@@ -0,0 +1,403 @@
+/*
+ *  OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ *  Copyright (C) 2021 Selva Nair 
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation, either version 2 of the License,
+ *  or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+#include "manage.h"
+#include "xkey_common.h"
+
+#ifdef HAVE_XKEY_PROVIDER
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct management *management; /* global */
+static int mgmt_callback_called;
+
+#ifndef _countof
+#define _countof(x) sizeof((x))/sizeof(*(x))
+#endif
+
+static OSSL_PROVIDER *prov[2];
+
+/* public keys for testing -- RSA and EC */
+static const char * const pubkey1 = "-BEGIN PUBLIC KEY-\n"
+"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7GWP6RLCGlvmVioIqYI6\n"
+"LUR4owA7sJ/nJxBAk+/xzD6gqgSigBsTqeb+gdZwkKjY1N4w2DUA0r5i8Eja/BWN\n"
+"xMZtC5nxK4MACtMqIwvlzfk130NhFXKtlZj2cyFBXqDdRyeg1ZrUQagcHVcgcReP\n"
+"9yiePgfO7NUOQk8edEeOR53SFCgnLBQQ9dGWtZN0hO/5BN6NSm/fd6vq0VjTRP5a\n"
+"BAH/BnqX9/3jV0jh8N9AE59mI1rjVVQ9VDnuAPkS8dLfdC661/CNxt0YWByTIgt1\n"
+"+qjW4LUvLbnU/rlPhuJ1SBZg+z/JtDBCKfs7syu5WYFqRvNFg7/91Rr/NwxvW/1h\n"
+"8QIDAQAB\n"
+"-END PUBLIC KEY-\n";
+
+static const char * const pubkey2 = "-BEGIN PUBLIC KEY-\n"
+"MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEO85iXW+HgnUkwlj1DohNVw0GsnGIh1gZ\n"
+"u95ff1JiUaJIkYNIkZA+hwIPFVH5aJcSCv3SPIeDS2VUAESNKHZJBQ==\n"
+"-END PUBLIC KEY-\n";
+
+static const char *pubkeys[] = {pubkey1, pubkey2};
+
+static const char *prov_name = "ovpn.xkey";
+
+static const char* test_msg = "Lorem ipsum dolor sit amet, consectetur "
+  "adipisici elit, sed eiusmod tempor incidunt "
+  "ut l

Re: [Openvpn-devel] [PATCH v3 17/18] xkey-provider: Add a test for generic key load and signature

2022-01-20 Thread Selva Nair
Hi

On Thu, Jan 20, 2022 at 9:51 AM Gert Doering  wrote:

> Hi,
>
> On Tue, Dec 14, 2021 at 11:59:27AM -0500, selva.n...@gmail.com wrote:
> > From: Selva Nair 
> >
> > Signed-off-by: Selva Nair 
>
> Is it OK if I squash 16+17 together?  I dislike the "history churn"
> of modifying configure.ac and Makefile.am in 16 just to remove
> the AM_CONDITIONAL bits again in 17...
>

Yeah, a previous version had checking for OpenSSL version in configure.ac
and the AM_CONDITIONAL made sense only in that case.  I can send a
new 16/18 or please do squash 16 with 17.

Thanks,

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v2] crypto: Fix OPENSSL_FIPS enabled builds

2022-01-19 Thread Selva Nair
Hi,

Sorry for chiming in late:

On Wed, Jan 19, 2022 at 10:20 AM David Sommerseth <
open...@sf.lists.topphemmelig.net> wrote:

> From: David Sommerseth 
>
> On Fedora and RHEL/CentOS, the standard OpenSSL library has the FIPS
> module enabled by default.  On these platforms, the OPENSSL_FIPS macro
> is always defined via /usr/include/openssl/opensslconf-*.h.
>
> Without this fix, the following compilation error appears:
>
>   ./src/openvpn/crypto.c: In function ‘print_cipher’:
>   ./src/openvpn/crypto.c:1707:43: error: ‘cipher’ undeclared (first use in
> this function); did you mean ‘iphdr’?
>if (FIPS_mode() && !(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_FIPS))
>^~
>
> The EVP_CIPHER_fetch() and EVP_CIPHER_free() methods are also provided
> via the openssl_compat.h for older than OpenSSL 3.0.
>
> Signed-off-by: David Sommerseth 
> ---
>  src/openvpn/crypto.c | 4 
>  1 file changed, 4 insertions(+)
>
> diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
> index 5626e2b6..e489d453 100644
> --- a/src/openvpn/crypto.c
> +++ b/src/openvpn/crypto.c
> @@ -34,6 +34,7 @@
>  #include "error.h"
>  #include "integer.h"
>  #include "platform.h"
> +#include "openssl_compat.h"
>
>  #include "memdbg.h"
>
> @@ -1704,10 +1705,13 @@ print_cipher(const char *ciphername)
>  printf(", TLS client/server mode only");
>  }
>  #ifdef OPENSSL_FIPS
> +evp_cipher_type *cipher = EVP_CIPHER_fetch(NULL, ciphername, NULL);
> +
>  if (FIPS_mode() && !(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_FIPS))
>

We need to check that cipher is not NULL. Fetch can return NULL while
EVP_CIPHER_flags() requires a non-null argument. Something like: if (cipher
&& FIPS_mode && etc...) will do.

EVP_CIPHER_free() below can handle NULL, so no problem there.



   {
>  printf(", disabled by FIPS mode");
>  }
> +EVP_CIPHER_free(cipher);

 #endif
>
>  printf(")\n");
>

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v2] tun: remove tun_finalize()

2022-01-15 Thread Selva Nair
Hi,

On Sat, Jan 15, 2022 at 3:25 AM Antonio Quartulli  wrote:
>
> Hi Selva,
>
> we were hoping to hear your opinion on this :-)
>
> We spent quite some time figuring out if we have to use both the non-WSA
> and the WSA variant of the API in our code, and it seems we have to.
>
> (not because using one variant only would not work, but rather because
> the spec demands using WSA with sockets and non-WSA with file handles)
>
> What's your take?
> Assuming you agree with us, does this patch look reasonable to you?

As far as I know, the reason for identical sounding functions with and
without WSA prefix is mostly historical. e.g.,  WSAGet/SetLastError()
and Get/SetLastError() are likely identical functions internally.
Tests show error code set by one is overwritten by the other etc.

That said, it's better to stick to the docs and use WSA functions with
sockets as opposed to file handles. In any case we have to distinguish
the two for GetOverlappedResult() as the WSA version also returns an
additional flag.

The way I see it, the patch is eliminating a chunk of nearly identical
code, and use of an ambivalent struct holding socket/file-handle and a
few macros is a small price to pay for that.

So, looks reasonable to me assuming any effect on performance is negligible.

A minor thing:
+
+#define SocketHandleSetLastError(sh, ...) (sh.is_handle ? \
+SetLastError(__VA_ARGS__) : WSASetLastError(__VA_ARGS__))

Why __VA_ARGS__?
As SetLastError() takes a single argument, wouldn't

#define SocketHandleSetLastError(sh, err) (sh.is_handle ?
SetLastError(err) : WSASetLastError(err))

be better?

Selva


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v2] fix Changes.rst errors in 2.5.3 and 2.5.5 announcement

2021-12-27 Thread Selva Nair
Acked-By:  Selva Nair 

On Mon, Dec 27, 2021 at 3:17 PM Gert Doering  wrote:
>
> - 2.5.3 had a typo in the CVE ID (CVE-2121-3606 should be -2021-)
> - 2.5.5 had windows paths with backslashes, which need to be doubled
>
> (CVE ID typo also reported by "@attritionorg" in Github PR 165)
>
> v2: SSL -> ssl, and .cfg -> .cnf
>
> Signed-off-by: Gert Doering 
> ---
>  Changes.rst | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/Changes.rst b/Changes.rst
> index b6f98d51..4e4f2018 100644
> --- a/Changes.rst
> +++ b/Changes.rst
> @@ -18,8 +18,8 @@ New features
>  - Windows build: use CFG and Spectre mitigations on MSVC builds
>
>  - bring back OpenSSL config loading to Windows builds.
> -  OpenSSL config is loaded from %installdir%\SSL\openssl.cfg
> -  (typically: c:\program files\openvpn\SSL\openssl.cfg) if it exists.
> +  OpenSSL config is loaded from %installdir%\\ssl\\openssl.cnf
> +  (typically: c:\\program files\\openvpn\\ssl\\openssl.cnf) if it exists.
>
>This is important for some hardware tokens which need special
>OpenSSL config for correct operation.  Trac #1296
> @@ -102,7 +102,7 @@ Overview of changes in 2.5.3
>  
>  Bugfixes
>  
> -- CVE-2121-3606
> +- CVE-2021-3606
>see https://community.openvpn.net/openvpn/wiki/SecurityAnnouncements
>
>OpenVPN windows builds could possibly load OpenSSL Config files from

--
Selva


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] fix Changes.rst errors in 2.5.3 and 2.5.5 announcement

2021-12-27 Thread Selva Nair
Hi

On Mon, Dec 27, 2021 at 6:16 AM Gert Doering  wrote:
>
> - 2.5.3 had a typo in the CVE ID (CVE-2121-3606 should be -2021-)
> - 2.5.5 had windows paths with backslashes, which need to be doubled
>
> (CVE ID typo also reported by "@attritionorg" in Github PR 165)
>
> Signed-off-by: Gert Doering 
> ---
>  Changes.rst | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/Changes.rst b/Changes.rst
> index b6f98d51..3d484318 100644
> --- a/Changes.rst
> +++ b/Changes.rst
> @@ -18,8 +18,8 @@ New features
>  - Windows build: use CFG and Spectre mitigations on MSVC builds
>
>  - bring back OpenSSL config loading to Windows builds.
> -  OpenSSL config is loaded from %installdir%\SSL\openssl.cfg
> -  (typically: c:\program files\openvpn\SSL\openssl.cfg) if it exists.
> +  OpenSSL config is loaded from %installdir%\\SSL\\openssl.cfg
> +  (typically: c:\\program files\\openvpn\\SSL\\openssl.cfg) if it exists.

"openssl.cfg" --> "openssl.cnf" please (x2)

Also, we use "ssl" instead of "SSL" in the source (win32.c). If the
installer also creates the folder as "ssl" it is arguably "more
correct" to use the lowercase name in documentation as that's how it
will show up in the file system. I haven't checked what case the
installer uses. Just nit-picking.

Selva


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH v3 18/18] Add xkey_provider sources and includes to MSVC project

2021-12-14 Thread selva . nair
From: Selva Nair 

Signed-off-by: Selva Nair 
---
 src/openvpn/openvpn.vcxproj | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/openvpn/openvpn.vcxproj b/src/openvpn/openvpn.vcxproj
index 65ee6839..2f0cee60 100644
--- a/src/openvpn/openvpn.vcxproj
+++ b/src/openvpn/openvpn.vcxproj
@@ -316,6 +316,8 @@
 
 
 
+
+
   
   
 
@@ -407,6 +409,7 @@
 
 
 
+
   
   
 
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH v3 14/18] pkcs11: Interface the xkey provider with pkcs11-helper

2021-12-14 Thread selva . nair
From: Selva Nair 

- Load the 'private key' handle through the provider and set it in
  SSL_CTX
- Add a sign op function to interface provider with pkcs11-helper.
  Previously we used its "OpenSSL Session" which internally sets up
  callbacks in RSA and EC key methods. Not useful for the provider
  interface, so, we directly call the PKCS#11 sign operation
  as done with mbedTLS.
- tls_libctx is made global for accessing from pkcs11_openssl.c

  Supports ECDSA and RSA_PKCS1_PADDING signatures. PSS support
  will be added when pkcs11-helper with our PR for specifying
  CK_MECHANISM variable in sign operations is released.
  (i.e., next release of pkcs11-helper).

Signed-off-by: Selva Nair 
---
 src/openvpn/pkcs11_openssl.c | 151 +++
 src/openvpn/ssl_openssl.c|   2 +-
 src/openvpn/xkey_common.h|   2 +
 3 files changed, 154 insertions(+), 1 deletion(-)

diff --git a/src/openvpn/pkcs11_openssl.c b/src/openvpn/pkcs11_openssl.c
index b29504b6..9cf46b2c 100644
--- a/src/openvpn/pkcs11_openssl.c
+++ b/src/openvpn/pkcs11_openssl.c
@@ -39,12 +39,163 @@
 #include "errlevel.h"
 #include "pkcs11_backend.h"
 #include "ssl_verify.h"
+#include "xkey_common.h"
 #include 
 
+#ifdef HAVE_XKEY_PROVIDER
+static XKEY_EXTERNAL_SIGN_fn xkey_pkcs11h_sign;
+
+/**
+ * Sign op called from xkey provider
+ *
+ * We support ECDSA, RSA_NO_PADDING, RSA_PKCS1_PADDING
+ */
+static int
+xkey_pkcs11h_sign(void *handle, unsigned char *sig,
+size_t *siglen, const unsigned char *tbs, size_t tbslen, 
XKEY_SIGALG sigalg)
+{
+pkcs11h_certificate_t cert = handle;
+CK_MECHANISM mech = {CKM_RSA_PKCS, NULL, 0}; /* default value */
+
+unsigned char buf[EVP_MAX_MD_SIZE];
+size_t buflen;
+
+if (!strcmp(sigalg.op, "DigestSign"))
+{
+dmsg(D_LOW, "xkey_pkcs11h_sign: computing digest");
+if (xkey_digest(tbs, tbslen, buf, , sigalg.mdname))
+{
+tbs = buf;
+tbslen = (size_t) buflen;
+sigalg.op = "Sign";
+}
+else
+{
+return 0;
+}
+}
+
+if (!strcmp(sigalg.keytype, "EC"))
+{
+mech.mechanism = CKM_ECDSA;
+}
+else if (!strcmp(sigalg.keytype, "RSA"))
+{
+if (!strcmp(sigalg.padmode,"none"))
+{
+mech.mechanism = CKM_RSA_X_509;
+}
+else if (!strcmp(sigalg.padmode, "pss"))
+{
+msg(M_NONFATAL, "PKCS#11: Error: PSS padding is not yet 
supported.");
+return 0;
+}
+else if (!strcmp(sigalg.padmode, "pkcs1"))
+{
+/* CMA_RSA_PKCS needs pkcs1 encoded digest */
+
+unsigned char enc[EVP_MAX_MD_SIZE + 32]; /* 32 bytes enough for 
DigestInfo header */
+size_t enc_len = sizeof(enc);
+
+if (!encode_pkcs1(enc, _len, sigalg.mdname, tbs, tbslen))
+{
+return 0;
+}
+tbs = enc;
+tbslen = enc_len;
+}
+else /* should not happen */
+{
+msg(M_WARN, "PKCS#11: Unknown padmode <%s>", sigalg.padmode);
+}
+}
+else
+{
+ ASSERT(0); /* coding error -- we couldnt have created any such key */
+}
+
+return CKR_OK == pkcs11h_certificate_signAny(cert, mech.mechanism,
+ tbs, tbslen, sig, siglen);
+}
+
+/* wrapper for handle free */
+static void
+xkey_handle_free(void *handle)
+{
+pkcs11h_certificate_freeCertificate(handle);
+}
+
+
+/**
+ * Load certificate and public key from pkcs11h to SSL_CTX
+ * through xkey provider.
+ *
+ * @param certificate  pkcs11h certificate object
+ * @param ctx  OpenVPN root tls context
+ *
+ * @returns1 on success, 0 on error to match
+ * other xkey_load_.. routines
+ */
+static int
+xkey_load_from_pkcs11h(pkcs11h_certificate_t certificate,
+struct tls_root_ctx *const ctx)
+{
+int ret = 0;
+
+X509 *x509 = pkcs11h_openssl_getX509(certificate);
+if (!x509)
+{
+msg(M_WARN, "PKCS#11: Unable get x509 certificate object");
+return 0;
+}
+
+EVP_PKEY *pubkey = X509_get0_pubkey(x509);
+
+XKEY_PRIVKEY_FREE_fn *free_op = xkey_handle_free; /* it calls 
pkcs11h_..._freeCertificate() */
+XKEY_EXTERNAL_SIGN_fn *sign_op = xkey_pkcs11h_sign;
+
+EVP_PKEY *pkey = xkey_load_generic_key(tls_libctx, certificate, pubkey, 
sign_op, free_op);
+if (!pkey)
+{
+msg(M_WARN, "PKCS#11: Failed to load private key into xkey provider");
+goto cleanup;
+}
+/* provider took ownership of the pkcs11h certificate object -- do not 
free below */
+certificate = NULL;
+
+if (!SSL_CTX_use_cert_and_key(ctx->ctx, 

[Openvpn-devel] [PATCH v3 15/18] Enable signing using CNG through xkey provider

2021-12-14 Thread selva . nair
From: Selva Nair 

- Add xkey_cng_sign() as sign_op for the provider
  and load the key using xkey_generic_load.

- Enable/Disable old code when provider is available or not.

- xkey_digest is made non-static for use in cryptoapi.c

One function cng_padding_type() is moved down to reduce number
of ifdef's.

Signed-off-by: Selva Nair 
---
 src/openvpn/cryptoapi.c | 241 +++-
 1 file changed, 211 insertions(+), 30 deletions(-)

diff --git a/src/openvpn/cryptoapi.c b/src/openvpn/cryptoapi.c
index 7fe3c57c..08cb434f 100644
--- a/src/openvpn/cryptoapi.c
+++ b/src/openvpn/cryptoapi.c
@@ -52,7 +52,9 @@
 #include "buffer.h"
 #include "openssl_compat.h"
 #include "win32.h"
+#include "xkey_common.h"
 
+#ifndef HAVE_XKEY_PROVIDER
 /* index for storing external data in EC_KEY: < 0 means uninitialized */
 static int ec_data_idx = -1;
 
@@ -61,44 +63,19 @@ static EVP_PKEY_METHOD *pmethod;
 static int (*default_pkey_sign_init) (EVP_PKEY_CTX *ctx);
 static int (*default_pkey_sign) (EVP_PKEY_CTX *ctx, unsigned char *sig,
  size_t *siglen, const unsigned char *tbs, 
size_t tbslen);
+#else
+static XKEY_EXTERNAL_SIGN_fn xkey_cng_sign;
+#endif /* HAVE_XKEY_PROVIDER */
 
 typedef struct _CAPI_DATA {
 const CERT_CONTEXT *cert_context;
 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE crypt_prov;
+EVP_PKEY *pubkey;
 DWORD key_spec;
 BOOL free_crypt_prov;
 int ref_count;
 } CAPI_DATA;
 
-/* Translate OpenSSL padding type to CNG padding type
- * Returns 0 for unknown/unsupported padding.
- */
-static DWORD
-cng_padding_type(int padding)
-{
-DWORD pad = 0;
-
-switch (padding)
-{
-case RSA_NO_PADDING:
-break;
-
-case RSA_PKCS1_PADDING:
-pad = BCRYPT_PAD_PKCS1;
-break;
-
-case RSA_PKCS1_PSS_PADDING:
-pad = BCRYPT_PAD_PSS;
-break;
-
-default:
-msg(M_WARN|M_INFO, "cryptoapicert: unknown OpenSSL padding type 
%d.",
-padding);
-}
-
-return pad;
-}
-
 /*
  * Translate OpenSSL hash OID to CNG algorithm name. Returns
  * "UNKNOWN" for unsupported algorithms and NULL for MD5+SHA1
@@ -164,9 +141,42 @@ CAPI_DATA_free(CAPI_DATA *cd)
 {
 CertFreeCertificateContext(cd->cert_context);
 }
+EVP_PKEY_free(cd->pubkey); /* passing NULL is okay */
+
 free(cd);
 }
 
+#ifndef HAVE_XKEY_PROVIDER
+
+/* Translate OpenSSL padding type to CNG padding type
+ * Returns 0 for unknown/unsupported padding.
+ */
+static DWORD
+cng_padding_type(int padding)
+{
+DWORD pad = 0;
+
+switch (padding)
+{
+case RSA_NO_PADDING:
+break;
+
+case RSA_PKCS1_PADDING:
+pad = BCRYPT_PAD_PKCS1;
+break;
+
+case RSA_PKCS1_PSS_PADDING:
+pad = BCRYPT_PAD_PSS;
+break;
+
+default:
+msg(M_WARN|M_INFO, "cryptoapicert: unknown OpenSSL padding type 
%d.",
+padding);
+}
+
+return pad;
+}
+
 /**
  * Sign the hash in 'from' using NCryptSignHash(). This requires an NCRYPT
  * key handle in cd->crypt_prov. On return the signature is in 'to'. Returns
@@ -255,6 +265,7 @@ ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM 
**kinvp, BIGNUM **rp)
 {
 return 1;
 }
+#endif /* HAVE_XKEY_PROVIDER */
 
 /**
  * Helper to convert ECDSA signature returned by NCryptSignHash
@@ -290,6 +301,8 @@ err:
 return NULL;
 }
 
+#ifndef HAVE_XKEY_PROVIDER
+
 /** EC_KEY_METHOD callback sign_sig(): sign and return an ECDSA_SIG pointer. */
 static ECDSA_SIG *
 ecdsa_sign_sig(const unsigned char *dgst, int dgstlen,
@@ -421,6 +434,8 @@ err:
 return 0;
 }
 
+#endif /* !HAVE_XKEY_PROVIDER */
+
 static const CERT_CONTEXT *
 find_certificate_in_store(const char *cert_prop, HCERTSTORE cert_store)
 {
@@ -521,6 +536,8 @@ out:
 return rv;
 }
 
+#ifndef HAVE_XKEY_PROVIDER
+
 static const CAPI_DATA *
 retrieve_capi_data(EVP_PKEY *pkey)
 {
@@ -765,6 +782,158 @@ cleanup:
 return ret;
 }
 
+#else /* HAVE_XKEY_PROVIDER */
+
+/** Sign hash in tbs using EC key in cd and NCryptSignHash */
+static int
+xkey_cng_ec_sign(CAPI_DATA *cd, unsigned char *sig, size_t *siglen, const 
unsigned char *tbs,
+ size_t tbslen)
+{
+BYTE buf[1024]; /* large enough for EC keys upto 1024 bits */
+DWORD len = _countof(buf);
+
+msg(D_LOW, "Signing using NCryptSignHash with EC key");
+
+DWORD status = NCryptSignHash(cd->crypt_prov, NULL, (BYTE *)tbs, tbslen, 
buf, len, , 0);
+
+if (status != ERROR_SUCCESS)
+{
+SetLastError(status);
+msg(M_NONFATAL|M_ERRNO, "Error in cryptoapicert: ECDSA signature using 
CNG failed.");
+return 0;
+}
+
+/* NCryptSignHash returns r|s -- convert to OpenSSL's ECDSA_SIG */
+ECDSA_SIG *ecsig = ecdsa_bin2sig(buf, len);
+if (!ecsig)
+{
+msg(M_NONFATAL, 

[Openvpn-devel] [PATCH v3 12/18] Increase ERR_BUF_SIZE when management interface support is enabled

2021-12-14 Thread selva . nair
From: Selva Nair 

Sending largish messages to the management interface errors due to
the limited size used for the "error" buffer in x_msg_va(). Although
all intermediate steps allocate required space for the data to
send, it gets truncated at the last step.

This really requires a smarter fix. As a quick relief, we just increase
the buffer size to 10240 when management support is compiled in. Should
be enough for PK_SIGN with undigested message.

Signed-off-by: Selva Nair 
---
 src/openvpn/error.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/openvpn/error.h b/src/openvpn/error.h
index 533354b3..66c1722e 100644
--- a/src/openvpn/error.h
+++ b/src/openvpn/error.h
@@ -37,8 +37,8 @@
 
 /* #define ABORT_ON_ERROR */
 
-#ifdef ENABLE_PKCS11
-#define ERR_BUF_SIZE 8192
+#if defined(ENABLE_PKCS11) || defined(ENABLE_MANAGEMENT)
+#define ERR_BUF_SIZE 10240
 #else
 #define ERR_BUF_SIZE 1280
 #endif
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH v3 04/18] Implement import of custom external keys

2021-12-14 Thread selva . nair
From: Selva Nair 

  Our key object retains info about the external
  key as an opaque handle to the backend. We also
  need the public key as an EVP_PKEY *.

  For native keys we use OpenSSL API to import
  data into the key. The 'handle' representing the
  private key in that case is the OpenSSL EVP_PKEY
  object itself.

  For importing custom keys, we define custom
  parameters describing the key using OSSL_PARAM
  structure. We define 4 required and 1 optional
  parameters for loading the key:

  Required params of type OSSL_PARAM:

  {.key="xkey-origin", .data_type = OSSL_PARAM_UTF8_STRING
   .data = "foobar", .data_size = 0 }

  Note: data_size = 0 refer to NUL terminated string in OpenSSL.
  This parameter is only used to identify that the key as non-native
  with an opaque handle. We really do not check the content of
  the string. Should not be NULL.

  {.key="handle", .data_type = OSSL_PARAM_OCTET_PTR,
   .data = , .data_size = sizeof(handle)}

  {.key="pubkey", .data_type = OSSL_PARAM_OCTET_STRING,
   .data = , .data_size = sizeof(pubkey)}

  {.key="sign_op", .data_type = OSSL_PARAM_OCTET_PTR,
   .data = _op_ptr, .data_size = sizeof(sign_op_ptr)}

  Optional param:

  {.key="free_op", .data_type = OSSL_PARAM_OCTET_PTR,
   .data = _op_ptr, .data_size = sizeof(free_op_ptr)}

  The 'handle' is opaque to us and is retained. The caller
  should not free it. We will free it when no longer required
  by calling 'free_op()', if provided. The 'handle' should
  not be NULL as that indicates missing private key.

  The 'pubkey' must be an 'EVP_PKEY *' variable, and is duplicated
  by us. The caller may free it after return from import.

  The 'sign_op' and 'free_op' function pointers should be of type
  'XKEY_EXTERNAL_SIGN_fn' and 'XKEY_PRIVKEY_FREE_fn' defined
  in xkey_common.h

For example, for management-external-key, we really do not
need any 'handle'. Pass anything that will live long and
won't dereference to NULL. We do not use it for any other
purpose. Pointer to a const string could be a choice.
In this case, free_op = NULL is the safest choice.

For a usage of keymgmt_import(), see the helper function
implemented using it to load the management key in the next commit.

v2 changes: "origin" --> "xkey-origin"
This was 5/9 in v1

Signed-off-by: Selva Nair 
---
 src/openvpn/xkey_provider.c | 135 +++-
 1 file changed, 133 insertions(+), 2 deletions(-)

diff --git a/src/openvpn/xkey_provider.c b/src/openvpn/xkey_provider.c
index 09138ae8..c2d560c5 100644
--- a/src/openvpn/xkey_provider.c
+++ b/src/openvpn/xkey_provider.c
@@ -78,6 +78,13 @@ typedef enum
  *
  * We also keep the public key in the form of a native OpenSSL EVP_PKEY.
  * This allows us to do all public ops by calling ops in the default provider.
+ * Both these are references retained by us and freed when the key is
+ * destroyed. As the pubkey is native, we free it using EVP_PKEY_free().
+ * To free the handle we call the backend if a free function
+ * has been set for that key. It could be set when the key is
+ * created/imported.
+ * For native keys, there is no need to free the handle as its either
+ * NULL of the same as the pubkey which we always free.
  */
 typedef struct
 {
@@ -133,6 +140,9 @@ static OSSL_FUNC_keymgmt_set_params_fn keymgmt_set_params;
 static OSSL_FUNC_keymgmt_query_operation_name_fn rsa_keymgmt_name;
 static OSSL_FUNC_keymgmt_query_operation_name_fn ec_keymgmt_name;
 
+static int
+keymgmt_import_helper(XKEY_KEYDATA *key, const OSSL_PARAM params[]);
+
 static XKEY_KEYDATA *
 keydata_new()
 {
@@ -156,6 +166,11 @@ keydata_free(XKEY_KEYDATA *key)
 {
 return;
 }
+if (key->free && key->handle)
+{
+key->free(key->handle);
+key->handle = NULL;
+}
 if (key->pubkey)
 {
 EVP_PKEY_free(key->pubkey);
@@ -195,7 +210,27 @@ keymgmt_load(const void *reference, size_t reference_sz)
  * appropriate for the key. We just use it to create a native
  * EVP_PKEY from params and assign to keydata->handle.
  *
- * Import of external keys -- to be implemented
+ * For non-native keys the params[] array should include a custom
+ * value with name "xkey-origin".
+ *
+ * Other required parameters in the params array are:
+ *
+ *  pubkey - pointer to native public key as a OCTET_STRING
+ *   the public key is duplicated on receipt
+ *  handle - reference to opaque handle to private key -- if not required
+ *   pass a dummy value that is not zero. type = OCTET_PTR
+ *   The reference is retained -- caller must _not_ free it.
+ *  sign_op - function pointer for sign operation. type = OCTET_PTR
+ *Must be a reference to XKEY_EXTERNAL_SIGN_fn
+ *  xkey-origin - A custom string to indicate the external key origin. 
UTF8_STRING
+ *The value doesn't really matter, but must b

[Openvpn-devel] [PATCH v3 02/18] Implement KEYMGMT in the xkey provider

2021-12-14 Thread selva . nair
From: Selva Nair 

A minimal set of functions for keymgmt are implemented.
No support for external key import as yet, only native
keys. Support for native keys is required as keys may
get imported into us for some operations as well as
for comparison with unexportable external keys that we hold.

Implementation of signature callbacks is in the next commit.

v2 changes: This was commit 3/9 in v1
v3 changes: When OpenSSL native key is imported instead of duplicating
the whole key, use only the public components for public key.

Signed-off-by: Selva Nair 
---
 src/openvpn/xkey_provider.c | 375 +++-
 1 file changed, 374 insertions(+), 1 deletion(-)

diff --git a/src/openvpn/xkey_provider.c b/src/openvpn/xkey_provider.c
index d47faf0a..a083ec2d 100644
--- a/src/openvpn/xkey_provider.c
+++ b/src/openvpn/xkey_provider.c
@@ -44,6 +44,9 @@
 #include 
 #include 
 
+/* propq set all on all ops we implement */
+static const char *const props = XKEY_PROV_PROPS;
+
 /* A descriptive name */
 static const char *provname = "OpenVPN External Key Provider";
 
@@ -59,6 +62,376 @@ typedef struct
   dmsg(f|M_NOPREFIX, __VA_ARGS__);  \
} while(0)
 
+typedef enum
+{
+ORIGIN_UNDEFINED = 0,
+OPENSSL_NATIVE, /* native key imported in */
+EXTERNAL_KEY
+} XKEY_ORIGIN;
+
+/**
+ * XKEY_KEYDATA: Our keydata encapsulation:
+ *
+ * We keep an opaque handle provided by the backend for the loaded
+ * key. It's passed back to the backend for any operation on private
+ * keys --- in practice, sign() op only.
+ *
+ * We also keep the public key in the form of a native OpenSSL EVP_PKEY.
+ * This allows us to do all public ops by calling ops in the default provider.
+ */
+typedef struct
+{
+/* opaque handle dependent on KEY_ORIGIN -- could be NULL */
+void *handle;
+/* associated public key as an openvpn native key */
+EVP_PKEY *pubkey;
+/* origin of key -- native or external */
+XKEY_ORIGIN origin;
+XKEY_PROVIDER_CTX *prov;
+int refcount;/* reference count */
+} XKEY_KEYDATA;
+
+#define KEYTYPE(key) ((key)->pubkey ? EVP_PKEY_get_id((key)->pubkey) : 0)
+#define KEYSIZE(key) ((key)->pubkey ? EVP_PKEY_get_size((key)->pubkey) : 0)
+
+/* keymgmt provider */
+
+/* keymgmt callbacks we implement */
+static OSSL_FUNC_keymgmt_new_fn keymgmt_new;
+static OSSL_FUNC_keymgmt_free_fn keymgmt_free;
+static OSSL_FUNC_keymgmt_load_fn keymgmt_load;
+static OSSL_FUNC_keymgmt_has_fn keymgmt_has;
+static OSSL_FUNC_keymgmt_match_fn keymgmt_match;
+static OSSL_FUNC_keymgmt_import_fn rsa_keymgmt_import;
+static OSSL_FUNC_keymgmt_import_fn ec_keymgmt_import;
+static OSSL_FUNC_keymgmt_import_types_fn keymgmt_import_types;
+static OSSL_FUNC_keymgmt_get_params_fn keymgmt_get_params;
+static OSSL_FUNC_keymgmt_gettable_params_fn keymgmt_gettable_params;
+static OSSL_FUNC_keymgmt_set_params_fn keymgmt_set_params;
+static OSSL_FUNC_keymgmt_query_operation_name_fn rsa_keymgmt_name;
+static OSSL_FUNC_keymgmt_query_operation_name_fn ec_keymgmt_name;
+
+static XKEY_KEYDATA *
+keydata_new()
+{
+xkey_dmsg(D_LOW, "entry");
+
+XKEY_KEYDATA *key = OPENSSL_zalloc(sizeof(*key));
+if (!key)
+{
+msg(M_NONFATAL, "xkey_keydata_new: out of memory");
+}
+
+return key;
+}
+
+static void
+keydata_free(XKEY_KEYDATA *key)
+{
+xkey_dmsg(D_LOW, "entry");
+
+if (!key || key->refcount-- > 0) /* free when refcount goes to zero */
+{
+return;
+}
+if (key->pubkey)
+{
+EVP_PKEY_free(key->pubkey);
+}
+OPENSSL_free(key);
+}
+
+static void *
+keymgmt_new(void *provctx)
+{
+xkey_dmsg(D_LOW, "entry");
+
+XKEY_KEYDATA *key = keydata_new();
+if (key)
+{
+key->prov = provctx;
+}
+
+return key;
+}
+
+static void *
+keymgmt_load(const void *reference, size_t reference_sz)
+{
+xkey_dmsg(D_LOW, "entry");
+
+return NULL;
+}
+
+/**
+ * Key import function
+ * When key operations like sign/verify are done in our context
+ * the key gets imported into us. We will also use import to
+ * load an external key into the provider.
+ *
+ * For native keys we get called with standard OpenSSL params
+ * appropriate for the key. We just use it to create a native
+ * EVP_PKEY from params and assign to keydata->handle.
+ *
+ * Import of external keys -- to be implemented
+ */
+static int
+keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[], const 
char *name)
+{
+xkey_dmsg(D_LOW, "entry");
+
+XKEY_KEYDATA *key = keydata;
+ASSERT(key);
+
+/* Our private key is immutable -- we import only if keydata is empty */
+if (key->handle || key->pubkey)
+{
+msg(M_WARN, "Error: keymgmt_import: keydata not empty -- our keys are 
immutable");
+return 0;
+}
+
+/* create a native public key and assign it

[Openvpn-devel] [PATCH v3 06/18] A helper function to import private key for management-external-key

2021-12-14 Thread selva . nair
From: Selva Nair 

- Leverage keymgmt_import through EVP_PKEY_new_fromdata() to
  import "management-external-key"

- When required, use this to set SSL_CTX_use_PrivateKey

The sign_op is not implemented yet. This will error out while
signing with --management-external-key. The next commit
fixes that.

Signed-off-by: Selva Nair 
---
 src/openvpn/Makefile.am   |   1 +
 src/openvpn/ssl_openssl.c |  11 
 src/openvpn/xkey_common.h |  11 
 src/openvpn/xkey_helper.c | 106 ++
 4 files changed, 129 insertions(+)
 create mode 100644 src/openvpn/xkey_helper.c

diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 432efe73..0331298b 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -129,6 +129,7 @@ openvpn_SOURCES = \
tun.c tun.h \
vlan.c vlan.h \
xkey_provider.c xkey_common.h \
+   xkey_helper.c \
win32.h win32.c \
win32-util.h win32-util.c \
cryptoapi.h cryptoapi.c
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index bdaa7a2b..23c74f55 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -1486,6 +1486,15 @@ tls_ctx_use_management_external_key(struct tls_root_ctx 
*ctx)
 EVP_PKEY *pkey = X509_get0_pubkey(cert);
 ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */
 
+#ifdef HAVE_XKEY_PROVIDER
+EVP_PKEY *privkey = xkey_load_management_key(tls_libctx, pkey);
+if (!privkey
+|| !SSL_CTX_use_PrivateKey(ctx->ctx, privkey))
+{
+goto cleanup;
+}
+EVP_PKEY_free(privkey);
+#else
 if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA)
 {
 if (!tls_ctx_use_external_rsa_key(ctx, pkey))
@@ -1514,6 +1523,8 @@ tls_ctx_use_management_external_key(struct tls_root_ctx 
*ctx)
 }
 #endif /* OPENSSL_VERSION_NUMBER > 1.1.0 dev && !defined(OPENSSL_NO_EC) */
 
+#endif /* HAVE_XKEY_PROVIDER */
+
 ret = 0;
 cleanup:
 if (ret)
diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h
index f46bacd2..5bda5e30 100644
--- a/src/openvpn/xkey_common.h
+++ b/src/openvpn/xkey_common.h
@@ -82,6 +82,17 @@ typedef int (XKEY_EXTERNAL_SIGN_fn)(void *handle, unsigned 
char *sig, size_t *si
  */
 typedef void (XKEY_PRIVKEY_FREE_fn)(void *handle);
 
+/**
+ * Generate an encapsulated EVP_PKEY for management-external-key
+ *
+ * @param libctx library context in which xkey provider has been loaded
+ * @param pubkey corresponding pubkey in the default provider's context
+ *
+ * @returns a new EVP_PKEY in the provider's keymgmt context.
+ * The pubkey is up-refd if retained -- the caller can free it after return
+ */
+EVP_PKEY *xkey_load_management_key(OSSL_LIB_CTX *libctx, EVP_PKEY *pubkey);
+
 #endif /* HAVE_XKEY_PROVIDER */
 
 #endif /* XKEY_COMMON_H_ */
diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c
new file mode 100644
index ..51cfb12b
--- /dev/null
+++ b/src/openvpn/xkey_helper.c
@@ -0,0 +1,106 @@
+/*
+ *  OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ *  Copyright (C) 2021 Selva Nair 
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation, either version 2 of the License,
+ *  or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include 
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+#include "error.h"
+#include "buffer.h"
+#include "xkey_common.h"
+
+#ifdef HAVE_XKEY_PROVIDER
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const char *const props = XKEY_PROV_PROPS;
+
+XKEY_EXTERNAL_SIGN_fn xkey_management_sign;
+
+/**
+ * Load external key for signing via management interface.
+ * The public key must be passed in by the caller as we may not
+ * be able to get it from the management.
+ * Returns an EVP_PKEY object attached to xkey provider.
+ * Caller must free it when no longer needed.
+ */
+EVP_PKEY *
+xkey_load_management_key(OSSL_LIB_CTX *libctx, EVP_PKEY *pubkey)
+{
+EVP_PKEY *pkey = NULL;
+ASSERT(pubkey);
+
+/* Management interface doesnt requir

[Openvpn-devel] [PATCH v3 13/18] Add a generic key loading helper function for xkey provider

2021-12-14 Thread selva . nair
From: Selva Nair 

- Load keys by specifying the opaque privtae key handle,
  public key, sign-op and free-op required for loading keys
  from Windows store and pkcs11.

- xkey_load_management_key is refactored to use the new function

- Also make xkey_digest non-static

Used in following commits to load CNG and pkcs11 keys

Signed-off-by: Selva Nair 
---
 src/openvpn/xkey_common.h | 35 +++
 src/openvpn/xkey_helper.c | 37 +++--
 2 files changed, 66 insertions(+), 6 deletions(-)

diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h
index c04c9c5c..e2ddc178 100644
--- a/src/openvpn/xkey_common.h
+++ b/src/openvpn/xkey_common.h
@@ -116,6 +116,41 @@ bool
 encode_pkcs1(unsigned char *enc, size_t *enc_len, const char *mdname,
  const unsigned char *tbs, size_t tbslen);
 
+/**
+ * Compute message digest
+ *
+ * @param src   pointer to message to be hashed
+ * @param srclenlength of data in bytes
+ * @param buf   pointer to output buffer
+ * @param buflen*buflen = capacity in bytes of output buffer
+ * @param mdnamename of the hash algorithm (SHA256, SHA1 etc.)
+ *
+ * @return  false on error, true  on success
+ *
+ * On successful return *buflen is set to the actual size of the result.
+ * TIP: EVP_MD_MAX_SIZE should be enough capacity of buf for al algorithms.
+ */
+int
+xkey_digest(const unsigned char *src, size_t srclen, unsigned char *buf,
+size_t *buflen, const char *mdname);
+
+/**
+ * Load a generic external key with custom sign and free ops
+ *
+ * @param libctxlibrary context in which xkey provider has been loaded
+ * @param handlean opaque handle to the backend -- passed to alll callbacks
+ * @param pubkeycorresponding pubkey in the default provider's context
+ * @param sign_op   private key signature operation to callback
+ * @param sign_op   private key signature operation to callback
+ *
+ * @returns a new EVP_PKEY in the provider's keymgmt context.
+ * IMPORTANT: a reference to the handle is retained by the provider and
+ * relased by callng free_op. The caller should not free it.
+ */
+EVP_PKEY *
+xkey_load_generic_key(OSSL_LIB_CTX *libctx, void *handle, EVP_PKEY *pubkey,
+  XKEY_EXTERNAL_SIGN_fn sign_op, XKEY_PRIVKEY_FREE_fn 
free_op);
+
 #endif /* HAVE_XKEY_PROVIDER */
 
 #endif /* XKEY_COMMON_H_ */
diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c
index d09ad635..19de64ff 100644
--- a/src/openvpn/xkey_helper.c
+++ b/src/openvpn/xkey_helper.c
@@ -50,8 +50,18 @@ static const char *const props = XKEY_PROV_PROPS;
 
 XKEY_EXTERNAL_SIGN_fn xkey_management_sign;
 
+static void
+print_openssl_errors()
+{
+unsigned long e;
+while ((e = ERR_get_error()))
+{
+msg(M_WARN, "OpenSSL error %lu: %s\n", e, ERR_error_string(e, NULL));
+}
+}
+
 /** helper to compute digest */
-static int
+int
 xkey_digest(const unsigned char *src, size_t srclen, unsigned char *buf,
 size_t *buflen, const char *mdname)
 {
@@ -85,24 +95,38 @@ xkey_digest(const unsigned char *src, size_t srclen, 
unsigned char *buf,
 EVP_PKEY *
 xkey_load_management_key(OSSL_LIB_CTX *libctx, EVP_PKEY *pubkey)
 {
-EVP_PKEY *pkey = NULL;
 ASSERT(pubkey);
 
-/* Management interface doesnt require any handle to be
+/* Management interface doesn't require any handle to be
  * stored in the key. We use a dummy pointer as we do need a
  * non-NULL value to indicate private key is avaialble.
  */
 void *dummy = & "dummy";
 
-const char *origin = "management";
 XKEY_EXTERNAL_SIGN_fn *sign_op = xkey_management_sign;
 
+return xkey_load_generic_key(libctx, dummy, pubkey, sign_op, NULL);
+}
+
+/**
+ * Load a generic key into the xkey provider.
+ * Returns an EVP_PKEY object attached to xkey provider.
+ * Caller must free it when no longer needed.
+ */
+EVP_PKEY *
+xkey_load_generic_key(OSSL_LIB_CTX *libctx, void *handle, EVP_PKEY *pubkey,
+  XKEY_EXTERNAL_SIGN_fn sign_op, XKEY_PRIVKEY_FREE_fn 
free_op)
+{
+EVP_PKEY *pkey = NULL;
+const char *origin = "external";
+
 /* UTF8 string pointers in here are only read from, so cast is safe */
 OSSL_PARAM params[] = {
 {"xkey-origin", OSSL_PARAM_UTF8_STRING, (char *) origin, 0, 0},
 {"pubkey", OSSL_PARAM_OCTET_STRING, , sizeof(pubkey), 0},
-{"handle", OSSL_PARAM_OCTET_PTR, , sizeof(dummy), 0},
+{"handle", OSSL_PARAM_OCTET_PTR, , sizeof(handle), 0},
 {"sign_op", OSSL_PARAM_OCTET_PTR, (void **) _op, sizeof(sign_op), 
0},
+{"free_op", OSSL_PARAM_OCTET_PTR, (void **) _op, sizeof(free_op), 
0},
 {NULL, 0, NULL, 0, 0}};
 
 /* Do not use EVP_PKEY_new_from_pkey as that will take keymgmt from pubkey 
*/
@@ -111,7 +135,8 @@ xkey_l

[Openvpn-devel] [PATCH v3 03/18] Implement SIGNATURE operations in xkey provider

2021-12-14 Thread selva . nair
From: Selva Nair 

- Basic frame work for announcing support for signature
  operations

- DigestSign and Sign functions for native keys are also
  implemented.  Though strictly not needed, these functions
  for native keys sets up the framework for signature operations.
  They also help loading an exportable key from a file through
  the provider for testing.

  Subsequent commits will add support for signing with
  external keys.

v2 changes:
  - Remove verify operations which are no longer
required with proposed changes in OpenSSL 3.0.1 that we target.

  - Undigested message is passed to the backend sign operation when
possible. This would allow more flexibility as some backends
prefer to do the hash operation internally.

  This was 4/9 in v1

Signed-off-by: Selva Nair 
---
 src/openvpn/xkey_common.h   |  43 +++
 src/openvpn/xkey_provider.c | 530 +++-
 2 files changed, 566 insertions(+), 7 deletions(-)

diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h
index a3bc3f2a..db58d077 100644
--- a/src/openvpn/xkey_common.h
+++ b/src/openvpn/xkey_common.h
@@ -40,6 +40,49 @@ OSSL_provider_init_fn xkey_provider_init;
 
 #define XKEY_PROV_PROPS "provider=ovpn.xkey"
 
+/**
+ * Stuct to encapsulate signature algorithm parameters to pass
+ * to sign operation.
+ */
+typedef struct {
+   const char *padmode; /**< "pkcs1", "pss" or "none" */
+   const char *mdname;  /**< "SHA256" or "SHA2-256" etc. */
+   const char *saltlen; /**< "digest", "auto" or "max" */
+   const char *keytype; /**< "EC" or "RSA" */
+   const char *op;  /**< "Sign" or "DigestSign" */
+} XKEY_SIGALG;
+
+/**
+ * Callback for sign operation -- must be implemented for each backend and
+ * is used in xkey_signature_sign(), or set when loading the key.
+ * (custom key loading not yet implemented).
+ *
+ * @param handle opaque key handle provided by the backend -- could be null
+ *   or unused for management interface.
+ * @param sigOn return caller should fill this with the signature
+ * @param siglen On entry *siglen has max size of sig and on return must be
+ *   set to the actual size of the signature
+ * @param tbsbuffer to sign
+ * @param tbslen size of data in tbs buffer
+ * @sigalg   contains the signature algorithm parameters
+ *
+ * @returns 1 on success, 0 on error.
+ *
+ * The data in tbs is just the digest with no DigestInfo header added. This is
+ * unlike the deprecated RSA_sign callback which provides encoded digest.
+ * For RSA_PKCS1 signatures, the external signing function must encode the 
digest
+ * before signing. The digest algorithm used is passed in the sigalg structure.
+ */
+typedef int (XKEY_EXTERNAL_SIGN_fn)(void *handle, unsigned char *sig, size_t 
*siglen,
+ const unsigned char *tbs, size_t tbslen,
+ XKEY_SIGALG sigalg);
+/**
+ * Signature of private key free function callback used
+ * to free the opaque private key handle obtained from the
+ * backend. Not required for management-external-key.
+ */
+typedef void (XKEY_PRIVKEY_FREE_fn)(void *handle);
+
 #endif /* HAVE_XKEY_PROVIDER */
 
 #endif /* XKEY_COMMON_H_ */
diff --git a/src/openvpn/xkey_provider.c b/src/openvpn/xkey_provider.c
index a083ec2d..09138ae8 100644
--- a/src/openvpn/xkey_provider.c
+++ b/src/openvpn/xkey_provider.c
@@ -81,18 +81,40 @@ typedef enum
  */
 typedef struct
 {
-/* opaque handle dependent on KEY_ORIGIN -- could be NULL */
+/** opaque handle dependent on KEY_ORIGIN -- could be NULL */
 void *handle;
-/* associated public key as an openvpn native key */
+/** associated public key as an openvpn native key */
 EVP_PKEY *pubkey;
-/* origin of key -- native or external */
+/** origin of key -- native or external */
 XKEY_ORIGIN origin;
+/** sign function in backend to call */
+XKEY_EXTERNAL_SIGN_fn *sign;
+/** keydata handle free function of backend */
+XKEY_PRIVKEY_FREE_fn *free;
 XKEY_PROVIDER_CTX *prov;
-int refcount;/* reference count */
+int refcount;/**< reference count */
 } XKEY_KEYDATA;
 
-#define KEYTYPE(key) ((key)->pubkey ? EVP_PKEY_get_id((key)->pubkey) : 0)
-#define KEYSIZE(key) ((key)->pubkey ? EVP_PKEY_get_size((key)->pubkey) : 0)
+static int
+KEYTYPE(const XKEY_KEYDATA *key)
+{
+return key->pubkey ? EVP_PKEY_get_id(key->pubkey) : 0;
+}
+
+static int
+KEYSIZE(const XKEY_KEYDATA *key)
+{
+return key->pubkey ? EVP_PKEY_get_size(key->pubkey) : 0;
+}
+
+/**
+ * Helper sign function for native keys
+ * Implemented using OpenSSL calls.
+ */
+int
+xkey_native_sign(XKEY_KEYDATA *key, unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs, size_t tbslen, XKEY_SIGALG sigalg);
+
 

[Openvpn-devel] [PATCH v3 10/18] Respect algorithm support announced by management client

2021-12-14 Thread selva . nair
From: Selva Nair 

Support for padding algorithms in management-client is indicated
in the optional argument to --management-external-key as "pkcs1",
"pss" etc. We currently use it only for an early exit based on heuristics
that a required algorithm may not be handled by the client. When
signature is requested we do not check whether the padding is indeed
supported by the client. This leads to situations like the client announcing
nopadding support but we request pss signature.

Here we add a check while requesting signature as well. If the padding
treat it as an error instead of submitting the request to the
management-interface regardless.

This change is made only when xkey provider is in use, though such a check
would be appropriate always.

Signed-off-by: Selva Nair 
---
 src/openvpn/xkey_helper.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c
index b2546cec..d63943d2 100644
--- a/src/openvpn/xkey_helper.c
+++ b/src/openvpn/xkey_helper.c
@@ -146,6 +146,8 @@ xkey_management_sign(void *unused, unsigned char *sig, 
size_t *siglen,
 unsigned char enc[EVP_MAX_MD_SIZE + 32]; /* 32 bytes enough for digest inf 
structure */
 size_t enc_len = sizeof(enc);
 
+unsigned int flags = management->settings.flags;
+
 if (!strcmp(alg.op, "DigestSign"))
 {
 dmsg(D_LOW, "xkey_management_sign: computing digest");
@@ -166,7 +168,7 @@ xkey_management_sign(void *unused, unsigned char *sig, 
size_t *siglen,
 strncpynt(alg_str, "ECDSA", sizeof(alg_str));
 }
 /* else assume RSA key */
-else if (!strcmp(alg.padmode, "pkcs1"))
+else if (!strcmp(alg.padmode, "pkcs1") && (flags & 
MF_EXTERNAL_KEY_PKCS1PAD))
 {
 /* management interface expects a pkcs1 encoded digest -- add it */
 if (!encode_pkcs1(enc, _len, alg.mdname, tbs, tbslen))
@@ -178,17 +180,17 @@ xkey_management_sign(void *unused, unsigned char *sig, 
size_t *siglen,
 
 strncpynt(alg_str, "RSA_PKCS1_PADDING", sizeof(alg_str));
 }
-else if (!strcmp(alg.padmode, "none"))
+else if (!strcmp(alg.padmode, "none") && (flags & 
MF_EXTERNAL_KEY_NOPADDING))
 {
 strncpynt(alg_str, "RSA_NO_PADDING", sizeof(alg_str));
 }
-else if (!strcmp(alg.padmode, "pss"))
+else if (!strcmp(alg.padmode, "pss") && (flags & MF_EXTERNAL_KEY_PSSPAD))
 {
 openvpn_snprintf(alg_str, sizeof(alg_str), "%s,hashalg=%s,saltlen=%s",
"RSA_PKCS1_PSS_PADDING", alg.mdname,alg.saltlen);
 }
 else {
-msg(M_NONFATAL, "Unsupported RSA padding mode in signature 
request<%s>",
+msg(M_NONFATAL, "RSA padding mode unknown or not supported by 
management-client <%s>",
 alg.padmode);
 return 0;
 }
-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH v3 01/18] A built-in provider for using external key with OpenSSL 3.0

2021-12-14 Thread selva . nair
From: Selva Nair 

Hooking into callbacks in RSA_METHOD and EVP_PKEY_METHOD
structures is deprecated in OpenSSL 3.0. For signing with
external keys that are not exportable (tokens, stores, etc.)
requires a custom provider interface so that key operations
are done under its context.

A single provider is enough for handling all external keys
we support -- management-external-key, cryptoapicert(CNG) and
pkcs11-helper. The series of patches starting with this implement
such a provider.

This patch implements only the provider_init function so
that it can be loaded, but has no capabilities. The required
interfaces are added in following commits.

v2 changes:
 - Require OpenSSL 3.0.1 or newer: 3.0.0 is "buggy" as it
   does not preferentially fetch operations from the keymgmt
   of the key. This causes either an unsuccessful attempt at
   exporting unexportable keys or an onerous requirement that
   the external key's KEYMGMT should support a whole lot
   of unrelated functionalities including key generation and
   key exchange.
   Fixed by PR #16725 in OpenSSL.
 - Use a child libctx for internal use in the provider

v3 changes:
 - Move OpenSSL version check for 3.0.1+ from configure to
   xkey_common.h

Signed-off-by: Selva Nair 
---
 src/openvpn/Makefile.am |   1 +
 src/openvpn/xkey_common.h   |  45 ++
 src/openvpn/xkey_provider.c | 169 
 3 files changed, 215 insertions(+)
 create mode 100644 src/openvpn/xkey_common.h
 create mode 100644 src/openvpn/xkey_provider.c

diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 5883c291..432efe73 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -128,6 +128,7 @@ openvpn_SOURCES = \
tls_crypt.c tls_crypt.h \
tun.c tun.h \
vlan.c vlan.h \
+   xkey_provider.c xkey_common.h \
win32.h win32.c \
win32-util.h win32-util.c \
cryptoapi.h cryptoapi.c
diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h
new file mode 100644
index ..a3bc3f2a
--- /dev/null
+++ b/src/openvpn/xkey_common.h
@@ -0,0 +1,45 @@
+/*
+ *  OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ *  Copyright (C) 2021 Selva Nair 
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation, either version 2 of the License,
+ *  or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef XKEY_COMMON_H_
+#define XKEY_COMMON_H_
+
+#include 
+#if OPENSSL_VERSION_NUMBER >= 0x3010L && !defined(DISABLE_XKEY_PROVIDER)
+#define HAVE_XKEY_PROVIDER 1
+
+#include 
+#include 
+
+/**
+ * Initialization function for OpenVPN external key provider for OpenSSL
+ * Follows the function signature of OSSL_PROVIDER init()
+ */
+OSSL_provider_init_fn xkey_provider_init;
+
+#define XKEY_PROV_PROPS "provider=ovpn.xkey"
+
+#endif /* HAVE_XKEY_PROVIDER */
+
+#endif /* XKEY_COMMON_H_ */
diff --git a/src/openvpn/xkey_provider.c b/src/openvpn/xkey_provider.c
new file mode 100644
index ..d47faf0a
--- /dev/null
+++ b/src/openvpn/xkey_provider.c
@@ -0,0 +1,169 @@
+/*
+ *  OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ *  Copyright (C) 2021 Selva Nair 
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation, either version 2 of the License,
+ *  or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 US

[Openvpn-devel] [PATCH v3 11/18] Support sending DigestSign request to management client

2021-12-14 Thread selva . nair
From: Selva Nair 

To receive undigested message for signing, indicate support
for handling message digesting in the client using an argument
"digest" to --management-external-key.

For example, to announce pkcs1 padding and digesting support use:

--management-external-key pkcs1 pss digest

In PK_SIGN, the algorithm string will get data=message
in addition to other relevant options.

Note that it is not guaranteed that the client will be prompted
with undigested message. This is possible only when OpenSSL
calls our provider for DigestSign() as opposed to Sign(). In
practice, signature operation always appears to result in
a DigestSign() call through the provider interface.

Signed-off-by: Selva Nair 
---
 src/openvpn/manage.h  |  1 +
 src/openvpn/options.c |  4 +++
 src/openvpn/xkey_helper.c | 52 ++-
 3 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/src/openvpn/manage.h b/src/openvpn/manage.h
index 5ed27c0c..9621f479 100644
--- a/src/openvpn/manage.h
+++ b/src/openvpn/manage.h
@@ -340,6 +340,7 @@ struct management *management_init(void);
 #define MF_QUERY_PROXY  (1<<14)
 #define MF_EXTERNAL_CERT(1<<15)
 #define MF_EXTERNAL_KEY_PSSPAD  (1<<16)
+#define MF_EXTERNAL_KEY_DIGEST  (1<<17)
 
 bool management_open(struct management *man,
  const char *addr,
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 3ec9025b..a323367c 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -5576,6 +5576,10 @@ add_option(struct options *options,
 {
 options->management_flags |= MF_EXTERNAL_KEY_PSSPAD;
 }
+else if (streq(p[j], "digest"))
+{
+options->management_flags |= MF_EXTERNAL_KEY_DIGEST;
+}
 else
 {
 msg(msglevel, "Unknown management-external-key flag: %s", 
p[j]);
diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c
index d63943d2..d09ad635 100644
--- a/src/openvpn/xkey_helper.c
+++ b/src/openvpn/xkey_helper.c
@@ -138,17 +138,22 @@ int
 xkey_management_sign(void *unused, unsigned char *sig, size_t *siglen,
  const unsigned char *tbs, size_t tbslen, XKEY_SIGALG alg)
 {
+dmsg(D_LOW, "In xkey_management_sign with keytype = %s, op = %s",
+ alg.keytype, alg.op);
+
 (void) unused;
 char alg_str[128];
 unsigned char buf[EVP_MAX_MD_SIZE]; /* for computing digest if required */
 size_t buflen = sizeof(buf);
 
-unsigned char enc[EVP_MAX_MD_SIZE + 32]; /* 32 bytes enough for digest inf 
structure */
+unsigned char enc[EVP_MAX_MD_SIZE + 32]; /* 32 bytes enough for digest 
info structure */
 size_t enc_len = sizeof(enc);
 
 unsigned int flags = management->settings.flags;
+bool is_message = !strcmp(alg.op, "DigestSign"); /* tbs is message, not 
digest */
 
-if (!strcmp(alg.op, "DigestSign"))
+/* if management client cannot do digest -- we do it here */
+if (!strcmp(alg.op, "DigestSign") && !(flags & MF_EXTERNAL_KEY_DIGEST))
 {
 dmsg(D_LOW, "xkey_management_sign: computing digest");
 if (xkey_digest(tbs, tbslen, buf, , alg.mdname))
@@ -156,6 +161,7 @@ xkey_management_sign(void *unused, unsigned char *sig, 
size_t *siglen,
 tbs = buf;
 tbslen = buflen;
 alg.op = "Sign";
+is_message = false;
 }
 else
 {
@@ -165,22 +171,38 @@ xkey_management_sign(void *unused, unsigned char *sig, 
size_t *siglen,
 
 if (!strcmp(alg.keytype, "EC"))
 {
-strncpynt(alg_str, "ECDSA", sizeof(alg_str));
+if (!strcmp(alg.op, "Sign"))
+{
+strncpynt(alg_str, "ECDSA", sizeof(alg_str));
+}
+else
+{
+openvpn_snprintf(alg_str, sizeof(alg_str), "ECDSA,hashalg=%s", 
alg.mdname);
+}
 }
 /* else assume RSA key */
 else if (!strcmp(alg.padmode, "pkcs1") && (flags & 
MF_EXTERNAL_KEY_PKCS1PAD))
 {
-/* management interface expects a pkcs1 encoded digest -- add it */
-if (!encode_pkcs1(enc, _len, alg.mdname, tbs, tbslen))
+/* For Sign, management interface expects a pkcs1 encoded digest -- 
add it */
+if (!strcmp(alg.op, "Sign"))
 {
-return 0;
+if (!encode_pkcs1(enc, _len, alg.mdname, tbs, tbslen))
+{
+return 0;
+}
+tbs = enc;
+tbslen = enc_len;
+strncpynt(alg_str, "RSA_PKCS1_PADDING", sizeof(alg_str));
+}
+/* For undigested message, add hashalg=digest parameter */
+else
+{
+openvpn_snprintf(alg_str, sizeof(alg_st

[Openvpn-devel] [PATCH v3 16/18] Add a unit test for external key provider

2021-12-14 Thread selva . nair
From: Selva Nair 

Tests:
- Check SIGNATURE and KEYMGMT methods can be fetched
  from the provider
- Load sample RSA and EC keys as management-external-key
  and check that their sign callbacks are correctly exercised:
  with and without digest support mocked in the client
  capability flag.

Signed-off-by: Selva Nair 
---
 configure.ac |   2 +
 tests/unit_tests/openvpn/Makefile.am |  20 ++
 tests/unit_tests/openvpn/test_provider.c | 305 +++
 3 files changed, 327 insertions(+)
 create mode 100644 tests/unit_tests/openvpn/test_provider.c

diff --git a/configure.ac b/configure.ac
index e0f9c332..c446f631 100644
--- a/configure.ac
+++ b/configure.ac
@@ -766,6 +766,8 @@ PKG_CHECK_MODULES(
[]
 )
 
+AM_CONDITIONAL([HAVE_XKEY_PROVIDER], [false])
+
 if test "${with_crypto_library}" = "openssl"; then
AC_ARG_VAR([OPENSSL_CFLAGS], [C compiler flags for OpenSSL])
AC_ARG_VAR([OPENSSL_LIBS], [linker flags for OpenSSL])
diff --git a/tests/unit_tests/openvpn/Makefile.am 
b/tests/unit_tests/openvpn/Makefile.am
index 44b77cc5..96b670ae 100644
--- a/tests/unit_tests/openvpn/Makefile.am
+++ b/tests/unit_tests/openvpn/Makefile.am
@@ -11,6 +11,10 @@ if HAVE_LD_WRAP_SUPPORT
 test_binaries += tls_crypt_testdriver
 endif
 
+if HAVE_XKEY_PROVIDER
+test_binaries += provider_testdriver
+endif
+
 TESTS = $(test_binaries)
 check_PROGRAMS = $(test_binaries)
 
@@ -95,6 +99,22 @@ networking_testdriver_SOURCES = test_networking.c mock_msg.c 
\
$(openvpn_srcdir)/platform.c
 endif
 
+if HAVE_XKEY_PROVIDER
+provider_testdriver_CFLAGS  = @TEST_CFLAGS@ \
+   -I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \
+   $(OPTIONAL_CRYPTO_CFLAGS)
+provider_testdriver_LDFLAGS = @TEST_LDFLAGS@ \
+   $(OPTIONAL_CRYPTO_LIBS)
+
+provider_testdriver_SOURCES = test_provider.c mock_msg.c \
+   $(openvpn_srcdir)/xkey_helper.c \
+   $(openvpn_srcdir)/xkey_provider.c \
+   $(openvpn_srcdir)/buffer.c \
+   $(openvpn_srcdir)/base64.c \
+   mock_get_random.c \
+   $(openvpn_srcdir)/platform.c
+endif
+
 auth_token_testdriver_CFLAGS  = @TEST_CFLAGS@ \
-I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \
$(OPTIONAL_CRYPTO_CFLAGS)
diff --git a/tests/unit_tests/openvpn/test_provider.c 
b/tests/unit_tests/openvpn/test_provider.c
new file mode 100644
index ..dcf39019
--- /dev/null
+++ b/tests/unit_tests/openvpn/test_provider.c
@@ -0,0 +1,305 @@
+/*
+ *  OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ *  Copyright (C) 2021 Selva Nair 
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation, either version 2 of the License,
+ *  or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "manage.h"
+#include "xkey_common.h"
+
+struct management *management; /* global */
+static int mgmt_callback_called;
+
+#ifndef _countof
+#define _countof(x) sizeof((x))/sizeof(*(x))
+#endif
+
+static OSSL_PROVIDER *prov[2];
+
+/* public keys for testing -- RSA and EC */
+static const char * const pubkey1 = "-BEGIN PUBLIC KEY-\n"
+"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7GWP6RLCGlvmVioIqYI6\n"
+"LUR4owA7sJ/nJxBAk+/xzD6gqgSigBsTqeb+gdZwkKjY1N4w2DUA0r5i8Eja/BWN\n"
+"xMZtC5nxK4MACtMqIwvlzfk130NhFXKtlZj2cyFBXqDdRyeg1ZrUQagcHVcgcReP\n"
+"9yiePgfO7NUOQk8edEeOR53SFCgnLBQQ9dGWtZN0hO/5BN6NSm/fd6vq0VjTRP5a\n"
+"BAH/BnqX9/3jV0jh8N9AE59mI1rjVVQ9VDnuAPkS8dLfdC661/CNxt0YWByTIgt1\n"
+"+qjW4LUvLbnU/rlPhuJ1SBZg+z/JtDBCKfs7syu5WYFqRvNFg7/91Rr/NwxvW/1h\n"
+"8QIDAQAB\n"
+"-END PUBLIC KEY-\n";
+
+static const char * const pubkey2 = "-BEGIN PUBLIC KEY-\n"
+"MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEO85iXW+HgnUkwlj1DohNVw0GsnGIh1gZ\n"
+"u95ff1JiUaJIkYNIkZA+hwIPFVH5aJcSCv3SPIeDS

[Openvpn-devel] [PATCH v3 09/18] Allow management client to announce pss padding support

2021-12-14 Thread selva . nair
From: Selva Nair 

The --management-external-key option can currently indicate support
for 'nopadding' or 'pkcs1' signatures in the client. Add 'pss' as an
option to announce that PSS signing requests are accepted.

To match, extend the algorithm string in PK_SIGN request to
include the following format:

- RSA_PKCS1_PSS_PADDING,hashlag=name,saltlen=[max|digest]

Here 'name' is the short common name of the hash algorithm.
E.g., SHA1, SHA256 etc.

Existing formats 'ECDSA' and 'RSA_PKCS1_PADDING' are unchanged.

v2 changes: Fix typos and other sloppiness in documentation and
commit message.

Signed-off-by: Selva Nair 
---
 doc/man-sections/management-options.rst |  8 +++-
 doc/management-notes.txt| 22 ++
 src/openvpn/manage.h|  1 +
 src/openvpn/options.c   | 11 ---
 4 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/doc/man-sections/management-options.rst 
b/doc/man-sections/management-options.rst
index de0d47e7..b173a1ea 100644
--- a/doc/man-sections/management-options.rst
+++ b/doc/man-sections/management-options.rst
@@ -90,9 +90,15 @@ server and client mode operations.
  management-external-key
  management-external-key nopadding
  management-external-key pkcs1
+ management-external-key pss
+
+  or any combination like:
+  ::
+
  management-external-key nopadding pkcs1
+ management-external-key pkcs1 pss
 
-  The optional parameters :code:`nopadding` and :code:`pkcs1` signal
+  The optional parameters :code:`nopadding` :code:`pkcs1` and :code:`pss` 
signal
   support for different padding algorithms. See
   :code:`doc/mangement-notes.txt` for a complete description of this
   feature.
diff --git a/doc/management-notes.txt b/doc/management-notes.txt
index 84e3d04b..169a5efe 100644
--- a/doc/management-notes.txt
+++ b/doc/management-notes.txt
@@ -1019,10 +1019,24 @@ can be indicated in the signing request only if the 
client version is > 2"
 
 The currently defined padding algorithms are:
 
- - RSA_PKCS1_PADDING  -  PKCS1 padding and RSA signature
- - RSA_NO_PADDING -  No padding may be added for the signature
- - ECDSA  -  EC signature.
-
+ - RSA_PKCS1_PADDING-  PKCS1 padding and RSA signature
+ - RSA_NO_PADDING   -  No padding may be added for the signature
+ - ECDSA-  EC signature.
+ - RSA_PKCS1_PSS_PADDING,params -  RSA signature with PSS padding
+
+   The params for PSS are specified as 'hashalg=name,saltlen=[max|digest]'.
+
+   The hashalg names are short common names such as SHA256, SHA224, etc.
+   PSS saltlen="digest" means use the same size as the hash to sign, while
+   "max" indicates maximum possible saltlen which is
+   '(nbits-1)/8 - hlen - 2'. Here 'nbits' is the number of bits in the
+   key modulus and 'hlen' the size in octets of the hash.
+   (See: RFC 8017 sec 8.1.1 and 9.1.1)
+
+   In the case of PKCS1_PADDING, when the hash algorithm is not legacy
+   MD5-SHA1, the hash is encoded with DigestInfo header before presenting
+   to the management interface. This is identical to CKM_RSA_PKCS in Cryptoki
+   as well as what RSA_private_encrypt() in OpenSSL expects.
 
 COMMAND -- certificate (OpenVPN 2.4 or higher)
 --
diff --git a/src/openvpn/manage.h b/src/openvpn/manage.h
index 04dc98d1..5ed27c0c 100644
--- a/src/openvpn/manage.h
+++ b/src/openvpn/manage.h
@@ -339,6 +339,7 @@ struct management *management_init(void);
 #define MF_QUERY_REMOTE (1<<13)
 #define MF_QUERY_PROXY  (1<<14)
 #define MF_EXTERNAL_CERT(1<<15)
+#define MF_EXTERNAL_KEY_PSSPAD  (1<<16)
 
 bool management_open(struct management *man,
  const char *addr,
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index fb427410..3ec9025b 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -60,6 +60,7 @@
 #include "forward.h"
 #include "ssl_verify.h"
 #include "platform.h"
+#include "xkey_common.h"
 #include 
 
 #include "memdbg.h"
@@ -2207,14 +2208,14 @@ options_postprocess_verify_ce(const struct options 
*options,
 
 #endif /* ifdef ENABLE_MANAGEMENT */
 
-#if  defined(ENABLE_MANAGEMENT)
+#if defined(ENABLE_MANAGEMENT) && !defined(HAVE_XKEY_PROVIDER)
 if ((tls_version_max() >= TLS_VER_1_3)
 && (options->management_flags & MF_EXTERNAL_KEY)
 && !(options->management_flags & (MF_EXTERNAL_KEY_NOPADDING))
 )
 {
-msg(M_ERR, "management-external-key with OpenSSL 1.1.1 requires "
-"the nopadding argument/support");
+msg(M_FATAL, "management-external-key with TLS 1.3 or later requires "
+"nopadding argument/support");
 }
 #endif
 /*
@@ -5571,6 +5572

[Openvpn-devel] [PATCH v3 00/18] External key provider for use with OpenSSL 3

2021-12-14 Thread selva . nair
From: Selva Nair 

The following series of patches implement a built-in
provider for interfacing OpenSSL 3.0 when external 
keys are in use.

Essentially, to intercept the sign operation, the SSL_CTX
object has to be created with properties string set to 
prioritize our provider. In the provider we implement
only keymgmt and signature operations and specify the
property string as optional. That allows all operations
we do not provide to be used from the default provider.

Same as PR#161 https://github.com/OpenVPN/openvpn/pull/161
with fixup commits in there squashed and rebased to master.

Requires OpenSSL 3.0.1 (released on Dec 14, 2021) or
OpenSSL 3.0 or 3.1 dev branch post Oct 27. 

Selva Nair (18):
  A built-in provider for using external key with OpenSSL 3.0
  Implement KEYMGMT in the xkey provider
  Implement SIGNATURE operations in xkey provider
  Implement import of custom external keys
  Initialize the xkey provider and use it in SSL context
  A helper function to import private key for management-external-key
  Enable signing via provider for management-external-key
  Add a function to encode digests with PKCS1 DigestInfo wrapper
  Allow management client to announce pss padding support
  Respect algorithm support announced by management client
  Support sending DigestSign request to management client
  Increase ERR_BUF_SIZE when management interface support is enabled
  Add a generic key loading helper function for xkey provider
  pkcs11: Interface the xkey provider with pkcs11-helper
  Enable signing using CNG through xkey provider
  Add a unit test for external key provider
  xkey-provider: Add a test for generic key load and signature
  Add xkey_provider sources and includes to MSVC project

 doc/man-sections/management-options.rst  |8 +-
 doc/management-notes.txt |   22 +-
 src/openvpn/Makefile.am  |2 +
 src/openvpn/cryptoapi.c  |  241 -
 src/openvpn/error.h  |4 +-
 src/openvpn/manage.h |2 +
 src/openvpn/openssl_compat.h |8 +
 src/openvpn/openvpn.vcxproj  |3 +
 src/openvpn/options.c|   31 +-
 src/openvpn/options.h|2 +
 src/openvpn/pkcs11_openssl.c |  151 +++
 src/openvpn/ssl.c|5 +
 src/openvpn/ssl.h|6 +
 src/openvpn/ssl_mbedtls.c|6 +
 src/openvpn/ssl_openssl.c|  108 +-
 src/openvpn/xkey_common.h|  158 +++
 src/openvpn/xkey_helper.c|  393 +++
 src/openvpn/xkey_provider.c  | 1189 ++
 tests/unit_tests/openvpn/Makefile.am |   16 +
 tests/unit_tests/openvpn/test_provider.c |  403 
 20 files changed, 2715 insertions(+), 43 deletions(-)
 create mode 100644 src/openvpn/xkey_common.h
 create mode 100644 src/openvpn/xkey_helper.c
 create mode 100644 src/openvpn/xkey_provider.c
 create mode 100644 tests/unit_tests/openvpn/test_provider.c

-- 
2.30.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH v3 05/18] Initialize the xkey provider and use it in SSL context

2021-12-14 Thread selva . nair
From: Selva Nair 

- Add function to check when external key is in use

- Load xkey provider into a custom library context when required

- Use the custom libctx in SSL CTX when external key is in use

As no keys are yet loaded through the provider,
no functionality gets delegated to it as yet.

v2 changes: Provider loading is reworked to activate only when external
keys are in use
This was 2/9 in v1

Signed-off-by: Selva Nair 
---
 src/openvpn/openssl_compat.h |  8 
 src/openvpn/options.c| 16 +++
 src/openvpn/options.h|  2 +
 src/openvpn/ssl.c|  5 ++
 src/openvpn/ssl.h|  6 +++
 src/openvpn/ssl_mbedtls.c|  6 +++
 src/openvpn/ssl_openssl.c| 93 +++-
 src/openvpn/xkey_common.h|  1 -
 8 files changed, 134 insertions(+), 3 deletions(-)

diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h
index dcc210c7..5c9da9eb 100644
--- a/src/openvpn/openssl_compat.h
+++ b/src/openvpn/openssl_compat.h
@@ -760,6 +760,14 @@ int EVP_PKEY_get_group_name(EVP_PKEY *pkey, char *gname, 
size_t gname_sz,
 #define EVP_CIPHER_get0_name EVP_CIPHER_name
 #define EVP_CIPHER_CTX_get_mode EVP_CIPHER_CTX_mode
 
+/** Reduce SSL_CTX_new_ex() to SSL_CTX_new() for OpenSSL < 3 */
+#define SSL_CTX_new_ex(libctx, propq, method)\
+SSL_CTX_new((method))
+
+/* Some safe typedefs to avoid too many ifdefs */
+typedef void OSSL_LIB_CTX;
+typedef void OSSL_PROVIDER;
+
 /* Mimics the functions but only when the default context without
  * options is chosen */
 static inline const EVP_CIPHER *
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index b840b767..fb427410 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -5337,6 +5337,22 @@ show_compression_warning(struct compress_options *info)
 }
 #endif
 
+bool key_is_external(const struct options *options)
+{
+bool ret = false;
+#ifdef ENABLE_MANAGEMENT
+ret = ret || (options->management_flags & MF_EXTERNAL_KEY);
+#endif
+#ifdef ENABLE_PKCS11
+ret = ret || (options->pkcs11_providers[0] != NULL);
+#endif
+#ifdef ENABLE_CRYPTOAPI
+ret = ret || options->cryptoapi_cert;
+#endif
+
+return ret;
+}
+
 static void
 add_option(struct options *options,
char *p[],
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index d4f41cd7..8dc06343 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -862,4 +862,6 @@ void options_string_import(struct options *options,
unsigned int *option_types_found,
struct env_set *es);
 
+bool key_is_external(const struct options *options);
+
 #endif /* ifndef OPTIONS_H */
diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index 05096ee0..0c4e3234 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -603,6 +603,11 @@ init_ssl(const struct options *options, struct 
tls_root_ctx *new_ctx, bool in_ch
 
 tls_clear_error();
 
+if (key_is_external(options))
+{
+load_xkey_provider();
+}
+
 if (options->tls_server)
 {
 tls_ctx_server_new(new_ctx);
diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h
index b14453fe..784ddd32 100644
--- a/src/openvpn/ssl.h
+++ b/src/openvpn/ssl.h
@@ -627,4 +627,10 @@ show_available_tls_ciphers(const char *cipher_list,
 bool
 tls_session_generate_data_channel_keys(struct tls_session *session);
 
+/**
+ * Load ovpn.xkey provider used for external key signing
+ */
+void
+load_xkey_provider(void);
+
 #endif /* ifndef OPENVPN_SSL_H */
diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c
index 94605801..15cd8b16 100644
--- a/src/openvpn/ssl_mbedtls.c
+++ b/src/openvpn/ssl_mbedtls.c
@@ -1550,4 +1550,10 @@ get_ssl_library_version(void)
 return mbedtls_version;
 }
 
+void
+load_xkey_provider(void)
+{
+return; /* no external key provider in mbedTLS build */
+}
+
 #endif /* defined(ENABLE_CRYPTO_MBEDTLS) */
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index 724664bb..bdaa7a2b 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -45,6 +45,7 @@
 #include "ssl_common.h"
 #include "base64.h"
 #include "openssl_compat.h"
+#include "xkey_common.h"
 
 #ifdef ENABLE_CRYPTOAPI
 #include "cryptoapi.h"
@@ -69,6 +70,10 @@
 #include 
 #endif
 
+static OSSL_LIB_CTX *tls_libctx;
+
+static void unload_xkey_provider(void);
+
 /*
  * Allocate space in SSL objects in which to store a struct tls_session
  * pointer back to parent.
@@ -113,7 +118,7 @@ tls_ctx_server_new(struct tls_root_ctx *ctx)
 {
 ASSERT(NULL != ctx);
 
-ctx->ctx = SSL_CTX_new(SSLv23_server_method());
+ctx->ctx = SSL_CTX_new_ex(tls_libctx, NULL, SSLv23_server_method());
 
 if (ctx->ctx == NULL)
 {
@@ -131,7 +136,7 @@ tls_ctx_client_new(struct tls_root_ctx *ctx)
 {
 ASSERT(NULL != ctx);
 
-ctx->ctx = SSL_CTX_new(SSLv23_client

[Openvpn-devel] [PATCH v3 08/18] Add a function to encode digests with PKCS1 DigestInfo wrapper

2021-12-14 Thread selva . nair
From: Selva Nair 

The EVP_PKEY interface as well as provider passes the raw
digest to the sign() function. In case of RSA_PKCS1,
our management interface expects an encoded hash, which
has the DigestInfo header added as per PKCSv1.5 specs,
unless the hash algorithm is legacy MD5_SHA1.

Fix this by
 - add a function to perform the pkcs1 encoding before passing the
   data to sign to the management interface. The implementation
   is not pretty, but should work.
   (Unfortunately OpenSSL does not expose a function for this).

Note:
1. cryptoki interface used by pkcs11-helper also requires this
to be done before calling the Sign op. This will come handy there
too.
2. We have a similar function in ssl_mbedtls.c but its not prettier,
   and require porting.

v2 changes: Use hard-coded headers for known hash algorithms instead
of assembling it from the ASN.1 objects.

Signed-off-by: Selva Nair 
---
 src/openvpn/xkey_common.h |  20 ++
 src/openvpn/xkey_helper.c | 130 ++
 2 files changed, 150 insertions(+)

diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h
index 608afe99..c04c9c5c 100644
--- a/src/openvpn/xkey_common.h
+++ b/src/openvpn/xkey_common.h
@@ -96,6 +96,26 @@ typedef void (XKEY_PRIVKEY_FREE_fn)(void *handle);
  */
 EVP_PKEY *xkey_load_management_key(OSSL_LIB_CTX *libctx, EVP_PKEY *pubkey);
 
+/**
+ * Add PKCS1 DigestInfo to tbs and return the result in *enc.
+ *
+ * @param enc   pointer to output buffer
+ * @param enc_len   capacity in bytes of output buffer
+ * @param mdnamename of the hash algorithm (SHA256, SHA1 etc.)
+ * @param tbs   pointer to digest to be encoded
+ * @param tbslenlength of data in bytes
+ *
+ * @return  false on error, true  on success
+ *
+ * On return enc_len is  set to actual size of the result.
+ * enc is NULL or enc_len is not enough to store the result, it is set
+ * to the required size and false is returned.
+ *
+ */
+bool
+encode_pkcs1(unsigned char *enc, size_t *enc_len, const char *mdname,
+ const unsigned char *tbs, size_t tbslen);
+
 #endif /* HAVE_XKEY_PROVIDER */
 
 #endif /* XKEY_COMMON_H_ */
diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c
index aac78a2c..b2546cec 100644
--- a/src/openvpn/xkey_helper.c
+++ b/src/openvpn/xkey_helper.c
@@ -143,6 +143,9 @@ xkey_management_sign(void *unused, unsigned char *sig, 
size_t *siglen,
 unsigned char buf[EVP_MAX_MD_SIZE]; /* for computing digest if required */
 size_t buflen = sizeof(buf);
 
+unsigned char enc[EVP_MAX_MD_SIZE + 32]; /* 32 bytes enough for digest inf 
structure */
+size_t enc_len = sizeof(enc);
+
 if (!strcmp(alg.op, "DigestSign"))
 {
 dmsg(D_LOW, "xkey_management_sign: computing digest");
@@ -165,6 +168,14 @@ xkey_management_sign(void *unused, unsigned char *sig, 
size_t *siglen,
 /* else assume RSA key */
 else if (!strcmp(alg.padmode, "pkcs1"))
 {
+/* management interface expects a pkcs1 encoded digest -- add it */
+if (!encode_pkcs1(enc, _len, alg.mdname, tbs, tbslen))
+{
+return 0;
+}
+tbs = enc;
+tbslen = enc_len;
+
 strncpynt(alg_str, "RSA_PKCS1_PADDING", sizeof(alg_str));
 }
 else if (!strcmp(alg.padmode, "none"))
@@ -205,4 +216,123 @@ xkey_management_sign(void *unused, unsigned char *sig, 
size_t *siglen,
 return (*siglen > 0);
 }
 
+/**
+ * Add PKCS1 DigestInfo to tbs and return the result in *enc.
+ *
+ * @param enc   pointer to output buffer
+ * @param enc_len   capacity in bytes of output buffer
+ * @param mdnamename of the hash algorithm (SHA256, SHA1 etc.)
+ * @param tbs   pointer to digest to be encoded
+ * @param tbslenlength of data in bytes
+ *
+ * @return  false on error, true  on success
+ *
+ * On return enc_len is  set to actual size of the result.
+ * enc is NULL or enc_len is not enough to store the result, it is set
+ * to the required size and false is returned.
+ */
+bool
+encode_pkcs1(unsigned char *enc, size_t *enc_len, const char *mdname,
+ const unsigned char *tbs, size_t tbslen)
+{
+ASSERT(enc_len != NULL);
+ASSERT(tbs != NULL);
+
+/* Tabulate the digest info header for expected hash algorithms
+ * These were pre-computed using the DigestInfo definition:
+ * DigestInfo ::= SEQUENCE {
+ *digestAlgorithm DigestAlgorithmIdentifier,
+ *digest Digest }
+ * Also see the table in RFC 8017 section 9.2, Note 1.
+ */
+
+const unsigned char sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b,
+  0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 
0x14};
+const unsigned char sha256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 
0x86, 0x48,
+0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 
0x00, 0x04, 0x20};
+const u

[Openvpn-devel] [PATCH v3 07/18] Enable signing via provider for management-external-key

2021-12-14 Thread selva . nair
From: Selva Nair 

- Add a function to set as sign_op during key import. The
  function passes the signature request to management interface,
  and returns the result to the provider.

v2 changes: Method to do digest added to match the changes in
the provider signature callback.
TODO:
 - Allow passing the undigested message to management interface
 - Add pkcs1 DigestInfo header when required

Signed-off-by: Selva Nair 
---
 src/openvpn/ssl_openssl.c |   4 +-
 src/openvpn/xkey_common.h |   7 ++-
 src/openvpn/xkey_helper.c | 108 --
 3 files changed, 113 insertions(+), 6 deletions(-)

diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index 23c74f55..8f0281b1 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -1169,7 +1169,7 @@ end:
 }
 
 
-#ifdef ENABLE_MANAGEMENT
+#if defined(ENABLE_MANAGEMENT) && !defined(HAVE_XKEY_PROVIDER)
 
 /* encrypt */
 static int
@@ -1470,7 +1470,9 @@ err:
 return 0;
 }
 #endif /* OPENSSL_VERSION_NUMBER > 1.1.0 dev && !defined(OPENSSL_NO_EC) */
+#endif /* ENABLE_MANAGEMENT && !HAVE_XKEY_PROVIDER */
 
+#ifdef ENABLE_MANAGEMENT
 int
 tls_ctx_use_management_external_key(struct tls_root_ctx *ctx)
 {
diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h
index 5bda5e30..608afe99 100644
--- a/src/openvpn/xkey_common.h
+++ b/src/openvpn/xkey_common.h
@@ -67,10 +67,13 @@ typedef struct {
  *
  * @returns 1 on success, 0 on error.
  *
- * The data in tbs is just the digest with no DigestInfo header added. This is
+ * If sigalg.op = "Sign", the data in tbs is the digest. If sigalg.op = 
"DigestSign"
+ * it is the message that the backend should hash wih appropriate hash 
algorithm before
+ * signing. In the former case no DigestInfo header is added to tbs. This is
  * unlike the deprecated RSA_sign callback which provides encoded digest.
  * For RSA_PKCS1 signatures, the external signing function must encode the 
digest
- * before signing. The digest algorithm used is passed in the sigalg structure.
+ * before signing. The digest algorithm used (or to be used) is passed in the 
sigalg
+ * structure.
  */
 typedef int (XKEY_EXTERNAL_SIGN_fn)(void *handle, unsigned char *sig, size_t 
*siglen,
  const unsigned char *tbs, size_t tbslen,
diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c
index 51cfb12b..aac78a2c 100644
--- a/src/openvpn/xkey_helper.c
+++ b/src/openvpn/xkey_helper.c
@@ -32,6 +32,8 @@
 #include "error.h"
 #include "buffer.h"
 #include "xkey_common.h"
+#include "manage.h"
+#include "base64.h"
 
 #ifdef HAVE_XKEY_PROVIDER
 
@@ -48,6 +50,31 @@ static const char *const props = XKEY_PROV_PROPS;
 
 XKEY_EXTERNAL_SIGN_fn xkey_management_sign;
 
+/** helper to compute digest */
+static int
+xkey_digest(const unsigned char *src, size_t srclen, unsigned char *buf,
+size_t *buflen, const char *mdname)
+{
+dmsg(D_LOW, "In xkey_digest");
+EVP_MD *md = EVP_MD_fetch(NULL, mdname, NULL); /* from default context */
+if (!md)
+{
+msg(M_WARN, "WARN: xkey_digest: MD_fetch failed for <%s>", mdname);
+return 0;
+}
+
+unsigned int len = (unsigned int) *buflen;
+if (EVP_Digest(src, srclen, buf, , md, NULL) != 1)
+{
+msg(M_WARN, "WARN: xkey_digest: EVP_Digest failed");
+return 0;
+}
+EVP_MD_free(md);
+
+*buflen = len;
+return 1;
+}
+
 /**
  * Load external key for signing via management interface.
  * The public key must be passed in by the caller as we may not
@@ -94,13 +121,88 @@ xkey_load_management_key(OSSL_LIB_CTX *libctx, EVP_PKEY 
*pubkey)
 return pkey;
 }
 
-/* not yet implemented */
+/**
+ * Signature callback for xkey_provider with management-external-key
+ *
+ * @param handleUnused -- may be null
+ * @param sig   On successful return signature is in sig.
+ * @param siglenOn entry *siglen has length of buffer sig,
+ *  on successful return size of signature
+ * @param tbs   hash or message to be signed
+ * @param tbslenlen of data in dgst
+ * @param sigalgextra signature parameters
+ *
+ * @return  signature length or -1 on error.
+ */
 int
 xkey_management_sign(void *unused, unsigned char *sig, size_t *siglen,
  const unsigned char *tbs, size_t tbslen, XKEY_SIGALG alg)
 {
-msg(M_FATAL, "FATAL ERROR: A sign callback for this key is not 
implemented.");
-return 0;
+(void) unused;
+char alg_str[128];
+unsigned char buf[EVP_MAX_MD_SIZE]; /* for computing digest if required */
+size_t buflen = sizeof(buf);
+
+if (!strcmp(alg.op, "DigestSign"))
+{
+dmsg(D_LOW, "xkey_management_sign: computing digest");
+if (xkey_digest(tbs, tbslen, buf, , al

[Openvpn-devel] [PATCH v3 17/18] xkey-provider: Add a test for generic key load and signature

2021-12-14 Thread selva . nair
From: Selva Nair 

Signed-off-by: Selva Nair 
---
 configure.ac |   2 -
 tests/unit_tests/openvpn/Makefile.am |   4 -
 tests/unit_tests/openvpn/test_provider.c | 112 +--
 3 files changed, 105 insertions(+), 13 deletions(-)

diff --git a/configure.ac b/configure.ac
index c446f631..e0f9c332 100644
--- a/configure.ac
+++ b/configure.ac
@@ -766,8 +766,6 @@ PKG_CHECK_MODULES(
[]
 )
 
-AM_CONDITIONAL([HAVE_XKEY_PROVIDER], [false])
-
 if test "${with_crypto_library}" = "openssl"; then
AC_ARG_VAR([OPENSSL_CFLAGS], [C compiler flags for OpenSSL])
AC_ARG_VAR([OPENSSL_LIBS], [linker flags for OpenSSL])
diff --git a/tests/unit_tests/openvpn/Makefile.am 
b/tests/unit_tests/openvpn/Makefile.am
index 96b670ae..6b5c94ab 100644
--- a/tests/unit_tests/openvpn/Makefile.am
+++ b/tests/unit_tests/openvpn/Makefile.am
@@ -11,9 +11,7 @@ if HAVE_LD_WRAP_SUPPORT
 test_binaries += tls_crypt_testdriver
 endif
 
-if HAVE_XKEY_PROVIDER
 test_binaries += provider_testdriver
-endif
 
 TESTS = $(test_binaries)
 check_PROGRAMS = $(test_binaries)
@@ -99,7 +97,6 @@ networking_testdriver_SOURCES = test_networking.c mock_msg.c \
$(openvpn_srcdir)/platform.c
 endif
 
-if HAVE_XKEY_PROVIDER
 provider_testdriver_CFLAGS  = @TEST_CFLAGS@ \
-I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \
$(OPTIONAL_CRYPTO_CFLAGS)
@@ -113,7 +110,6 @@ provider_testdriver_SOURCES = test_provider.c mock_msg.c \
$(openvpn_srcdir)/base64.c \
mock_get_random.c \
$(openvpn_srcdir)/platform.c
-endif
 
 auth_token_testdriver_CFLAGS  = @TEST_CFLAGS@ \
-I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \
diff --git a/tests/unit_tests/openvpn/test_provider.c 
b/tests/unit_tests/openvpn/test_provider.c
index dcf39019..0182b3b4 100644
--- a/tests/unit_tests/openvpn/test_provider.c
+++ b/tests/unit_tests/openvpn/test_provider.c
@@ -29,6 +29,10 @@
 #endif
 
 #include "syshead.h"
+#include "manage.h"
+#include "xkey_common.h"
+
+#ifdef HAVE_XKEY_PROVIDER
 
 #include 
 #include 
@@ -37,9 +41,6 @@
 #include 
 #include 
 
-#include "manage.h"
-#include "xkey_common.h"
-
 struct management *management; /* global */
 static int mgmt_callback_called;
 
@@ -91,11 +92,11 @@ static const char *test_digest_b64 = 
"dzhlAB6WSMZXC67At5b5Zk1f0Lfb8zq/Asx4YYMgIO
  * --- the smallest size of the actual signature with the above
  * keys.
  */
-const uint8_t good_sig[] =
+static const uint8_t good_sig[] =
{0xd8, 0xa7, 0xd9, 0x81, 0xd8, 0xaa, 0xd8, 0xad, 0x20, 0xd9, 0x8a, 0xd8,
 0xa7, 0x20, 0xd8, 0xb3, 0xd9, 0x85, 0xd8, 0xb3, 0xd9, 0x85, 0x0};
 
-const char *good_sig_b64 = "2KfZgdiq2K0g2YrYpyDYs9mF2LPZhQA=";
+static const char *good_sig_b64 = "2KfZgdiq2K0g2YrYpyDYs9mF2LPZhQA=";
 
 static EVP_PKEY *
 load_pubkey(const char *pem)
@@ -155,10 +156,16 @@ management_query_pk_sig(struct management *man, const 
char *b64_data,
 if (strstr(algorithm, "data=message"))
 {
  expected_tbs = test_msg_b64;
+ assert_non_null(strstr(algorithm, "hashalg=SHA256"));
 }
-
 assert_string_equal(b64_data, expected_tbs);
 
+/* We test using ECDSA or PSS with saltlen = digest */
+if (!strstr(algorithm, "ECDSA"))
+{
+assert_non_null(strstr(algorithm, 
"RSA_PKCS1_PSS_PADDING,hashalg=SHA256,saltlen=digest"));
+}
+
 /* Return a predefined string as sig so that the caller
  * can confirm that this callback was exercised.
  */
@@ -230,7 +237,6 @@ digest_sign(EVP_PKEY *pkey)
 goto done;
 }
 
-
 /* sign with sig = NULL to get required siglen */
 assert_int_equal(EVP_DigestSign(mctx, sig, , (uint8_t*)test_msg, 
strlen(test_msg)), 1);
 assert_true(siglen > 0);
@@ -288,6 +294,90 @@ again:
 }
 }
 
+/* helpers for testing generic key load and sign */
+static int xkey_free_called;
+static int xkey_sign_called;
+static void
+xkey_free(void *handle)
+{
+xkey_free_called = 1;
+/* We use a dummy string as handle -- check its value */
+assert_string_equal(handle, "xkey_handle");
+}
+
+static int
+xkey_sign(void *handle, unsigned char *sig, size_t *siglen,
+  const unsigned char *tbs, size_t tbslen, XKEY_SIGALG s)
+{
+if (!sig)
+{
+*siglen = 256; /* some arbitrary size */
+return 1;
+}
+
+xkey_sign_called = 1; /* called with non-null sig */
+
+if (!strcmp(s.op, "DigestSign"))
+{
+assert_memory_equal(tbs, test_msg, strlen(test_msg));
+}
+else
+{
+assert_memory_equal(tbs, test_digest, sizeof(test_digest));
+}
+
+/* For the test use sha256 and PSS padding for RSA */
+assert_int_equal(OBJ_sn2nid(s.mdname), NID_sha256);
+if (!strcmp(s.keytype, "RSA"))
+{
+assert_string_equal(s.padmode, "pss"); /* we us

Re: [Openvpn-devel] [PATCH v3 7/9] Remove cipher_kt_t and change type to const char* in API

2021-12-10 Thread Selva Nair
Hi,

On Fri, Dec 10, 2021 at 8:09 AM Arne Schwabe  wrote:
>
> Make the external crypto consumer oblivious to the internal cipher
> type that both mbed TLS and OpenSSL use. This change is mainly done
> so the cipher type that is used can be stay a const type but instead
> of an SSL library type, we now use a simple string to identify a
> cipher. This has the disadvantages that we do a cipher lookup every
> time a function is called that needs to query properties of a cipher.
> But none of these queries are in a critical path.
>
> This patch also fixes the memory leaks introduced by the
> EVP_fetch_cipher commit by always freeing the EVP_CIPHER.
>
> This also changes kt->cipher to be always defined with the name of
> the cipher. This only affects the "none" cipher cipher which was
> previously represented by kt->cipher to be NULL.
>
> Patch v2: rebase on master
>
> Patch v3: fix errors with mbed TLS without having md_kt to const char * patch
>   also applied, fix logic inversion in tls_crypt_tk
>
> Signed-off-by: Arne Schwabe 

For the record, this fixes my substantial comments (essentially,
cipher_defined() called with NULL ciphername from init.c). That said I
had missed the missing ! in cipher_defined() in tls_crypt.c (now
fixed) and test failures that Gert identified...

Selva


> ---
>  src/openvpn/auth_token.c   |   2 +-
>  src/openvpn/crypto.c   |  32 +++---
>  src/openvpn/crypto.h   |   4 +-
>  src/openvpn/crypto_backend.h   |  77 ++---
>  src/openvpn/crypto_mbedtls.c   |  85 +-
>  src/openvpn/crypto_mbedtls.h   |   3 -
>  src/openvpn/crypto_openssl.c   | 151 ++---
>  src/openvpn/crypto_openssl.h   |  13 ++-
>  src/openvpn/init.c |  14 ++-
>  src/openvpn/openssl_compat.h   |   7 ++
>  src/openvpn/openvpn.h  |   2 -
>  src/openvpn/options.c  |   9 +-
>  src/openvpn/ssl.c  |   4 +-
>  src/openvpn/ssl_ncp.c  |  24 ++--
>  src/openvpn/tls_crypt.c|   4 +-
>  tests/unit_tests/openvpn/test_crypto.c |   4 +-
>  tests/unit_tests/openvpn/test_ncp.c|   6 +-
>  17 files changed, 274 insertions(+), 167 deletions(-)
>
> diff --git a/src/openvpn/auth_token.c b/src/openvpn/auth_token.c
> index 5d5cea7f6..5c947004e 100644
> --- a/src/openvpn/auth_token.c
> +++ b/src/openvpn/auth_token.c
> @@ -35,7 +35,7 @@ auth_token_kt(void)
>  {
>  struct key_type kt = { 0 };
>  /* We do not encrypt our session tokens */
> -kt.cipher = NULL;
> +kt.cipher = "none";
>  kt.digest = md_kt_get("SHA256");
>
>  if (!kt.digest)
> diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
> index a63a26195..0b47dec44 100644
> --- a/src/openvpn/crypto.c
> +++ b/src/openvpn/crypto.c
> @@ -680,7 +680,7 @@ crypto_adjust_frame_parameters(struct frame *frame,
>  crypto_overhead += packet_id_size(packet_id_long_form);
>  }
>
> -if (kt->cipher)
> +if (cipher_defined(kt->cipher))
>  {
>  crypto_overhead += cipher_kt_iv_size(kt->cipher);
>
> @@ -710,16 +710,16 @@ crypto_max_overhead(void)
>  }
>
>  static void
> -warn_insecure_key_type(const char *ciphername, const cipher_kt_t *cipher)
> +warn_insecure_key_type(const char *ciphername)
>  {
> -if (cipher_kt_insecure(cipher))
> +if (cipher_kt_insecure(ciphername))
>  {
>  msg(M_WARN, "WARNING: INSECURE cipher (%s) with block size less than 
> 128"
>  " bit (%d bit).  This allows attacks like SWEET32.  Mitigate by "
>  "using a --cipher with a larger block size (e.g. AES-256-CBC). "
>  "Support for these insecure ciphers will be removed in "
>  "OpenVPN 2.6.",
> -ciphername, cipher_kt_block_size(cipher)*8);
> +ciphername, cipher_kt_block_size(ciphername)*8);
>  }
>  }
>
> @@ -736,10 +736,10 @@ init_key_type(struct key_type *kt, const char 
> *ciphername,
>  ASSERT(authname);
>
>  CLEAR(*kt);
> +kt->cipher = ciphername;
>  if (strcmp(ciphername, "none") != 0)
>  {
> -kt->cipher = cipher_kt_get(ciphername);
> -if (!kt->cipher)
> +if (!cipher_valid(ciphername))
>  {
>  msg(M_FATAL, "Cipher %s not supported", ciphername);
>  }
> @@ -762,7 +762,7 @@ init_key_type(struct key_type *kt, const char *ciphername,
>  }
>  if (warn)
>  {
> -warn_insecure_key_type(ciphername, kt

Re: [Openvpn-devel] [PATCH v3 7/9] Remove cipher_kt_t and change type to const char* in API

2021-12-10 Thread Selva Nair
On Fri, Dec 10, 2021 at 10:09 AM Gert Doering  wrote:
>
> Hi,
>
> On Fri, Dec 10, 2021 at 02:06:51PM +0100, Arne Schwabe wrote:
> > Patch v3: fix errors with mbed TLS without having md_kt to const char * 
> > patch
> >   also applied, fix logic inversion in tls_crypt_tk
>
> Thanks, this is much better than v2 - now all client-side tests pass
> that led to "openvpn exiting" previously, or SIGSEGV'ing.
>
> *BUT* - it totally fails to work on a connection that negotiates BF-CBC,
> though, both with mbedTLS 2.27.0 and with OpenSSL 1.1.1l - I did not see
> it in the client side tests first (because I only ran a limited subset),
> but it is easily triggered by connecting to a 2.3 server, requiring
> fallback to BF-CBC.
>
> It also fails all server side tests that end up in trying to use BF-CBC
> (long e-mail cut short).
>
> Most notable indication is: with an older binary, I get these lines
> in the log:
>
> 2021-12-10 15:53:14 us=406619 cron2-freebsd-tc-amd64-24/194.97.140.21:40161 
> Outgoing Data Channel: Cipher 'BF-CBC' initialized with 128 bit key
> 2021-12-10 15:53:14 us=406645 cron2-freebsd-tc-amd64-24/194.97.140.21:40161 
> WARNING: INSECURE cipher (BF-CBC) with block size less than 128 bit (64 bit). 
>  This allows attacks like SWEET32.  Mitigate by using a --cipher with a 
> larger block size (e.g. AES-256-CBC). Support for these insecure ciphers will 
> be removed in OpenVPN 2.6.
>
> which are totally missing (!) for master + 7/9v3.

This may be related to this chunk:

@@ -2762,16 +2762,19 @@ do_init_crypto_tls_c1(struct context *c)

 * Note that BF-CBC will still be part of the OCC string to retain
 * backwards compatibility with older clients.
 */
+const char* ciphername = options->ciphername;
 if (!streq(options->ciphername, "BF-CBC")
 || tls_item_in_cipher_list("BF-CBC", options->ncp_ciphers)
 || options->enable_ncp_fallback)
 {
-/* Do not warn if the if the cipher is used only in OCC */
-bool warn = options->enable_ncp_fallback;
-init_key_type(>c1.ks.key_type, options->ciphername,
options->authname,
-  true, warn);
+ciphername = "none";
 }

+/* Do not warn if the cipher is used only in OCC */
+bool warn = options->enable_ncp_fallback;
+init_key_type(>c1.ks.key_type, ciphername, options->authname,
+  true, warn);
+

Selva


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v2 7/9] Remove cipher_kt_t and change type to const char* in API

2021-12-09 Thread Selva Nair
* Not user-specified */
>  {
> diff --git a/src/openvpn/ssl_ncp.c b/src/openvpn/ssl_ncp.c
> index 4b95406e9..ce82e8951 100644
> --- a/src/openvpn/ssl_ncp.c
> +++ b/src/openvpn/ssl_ncp.c
> @@ -105,8 +105,7 @@ mutate_ncp_cipher_list(const char *list, struct gc_arena 
> *gc)
>  while (token)
>  {
>  /*
> - * Going through a roundtrip by using cipher_kt_get/cipher_kt_name
> - * (and translate_cipher_name_from_openvpn/
> + * Going cipher_kt_name (and translate_cipher_name_from_openvpn/
>   * translate_cipher_name_to_openvpn) also normalises the cipher name,
>   * e.g. replacing AeS-128-gCm with AES-128-GCM
>   *
> @@ -114,15 +113,16 @@ mutate_ncp_cipher_list(const char *list, struct 
> gc_arena *gc)
>   * OpenVPN will only warn if they are not found (and remove them from
>   * the list)
>   */
> -
>  bool optional = false;
>  if (token[0] == '?')
>  {
>  token++;
>  optional = true;
>  }
> -const cipher_kt_t *ktc = cipher_kt_get(token);
> -if (strcmp(token, "none") == 0)
> +
> +const bool nonecipher = (strcmp(token, "none") == 0);
> +
> +if (nonecipher)
>  {
>  msg(M_WARN, "WARNING: cipher 'none' specified for 
> --data-ciphers. "
>  "This allows negotiation of NO encryption and "
> @@ -130,7 +130,7 @@ mutate_ncp_cipher_list(const char *list, struct gc_arena 
> *gc)
>  "over the network! "
>  "PLEASE DO RECONSIDER THIS SETTING!");
>  }
> -if (!ktc && strcmp(token, "none") != 0)
> +if (!nonecipher && !cipher_valid(token))
>  {
>  const char* optstr = optional ? "optional ": "";
>  msg(M_WARN, "Unsupported %scipher in --data-ciphers: %s", 
> optstr, token);
> @@ -138,8 +138,8 @@ mutate_ncp_cipher_list(const char *list, struct gc_arena 
> *gc)
>  }
>  else
>  {
> -const char *ovpn_cipher_name = cipher_kt_name(ktc);
> -if (ktc == NULL)
> +const char *ovpn_cipher_name = cipher_kt_name(token);
> +if (nonecipher)
>  {
>  /* NULL resolves to [null-cipher] but we need none for
>   * data-ciphers */
> @@ -466,17 +466,17 @@ p2p_mode_ncp(struct tls_multi *multi, struct 
> tls_session *session)
>  if (!common_cipher)
>  {
>  struct buffer out = alloc_buf_gc(128, );
> -const cipher_kt_t *cipher = session->opt->key_type.cipher;
> -
>  /* at this point we do not really know if our fallback is
>   * not enabled or if we use 'none' cipher as fallback, so
>   * keep this ambiguity here and print fallback-cipher: none
>   */
>
>  const char *fallback_name = "none";
> -if (cipher)
> +const char *ciphername = session->opt->key_type.cipher;
> +
> +if (cipher_defined(ciphername))
>  {
> -fallback_name = cipher_kt_name(cipher);
> +fallback_name = cipher_kt_name(ciphername);
>  }
>
>  buf_printf(, "(not negotiated, fallback-cipher: %s)", 
> fallback_name);
> diff --git a/src/openvpn/tls_crypt.c b/src/openvpn/tls_crypt.c
> index 80ed9684e..887943d74 100644
> --- a/src/openvpn/tls_crypt.c
> +++ b/src/openvpn/tls_crypt.c
> @@ -51,10 +51,10 @@ static struct key_type
>  tls_crypt_kt(void)
>  {
>  struct key_type kt;
> -kt.cipher = cipher_kt_get("AES-256-CTR");
> +kt.cipher = "AES-256-CTR";
>  kt.digest = md_kt_get("SHA256");
>
> -if (!kt.cipher)
> +if (cipher_valid(kt.cipher))
>  {
>  msg(M_WARN, "ERROR: --tls-crypt requires AES-256-CTR support.");
>  return (struct key_type) { 0 };
> diff --git a/tests/unit_tests/openvpn/test_crypto.c 
> b/tests/unit_tests/openvpn/test_crypto.c
> index 42632c72b..344817eef 100644
> --- a/tests/unit_tests/openvpn/test_crypto.c
> +++ b/tests/unit_tests/openvpn/test_crypto.c
> @@ -72,7 +72,7 @@ crypto_pem_encode_decode_loopback(void **state)
>  static void
>  test_translate_cipher(const char *ciphername, const char *openvpn_name)
>  {
> -const cipher_kt_t *cipher = cipher_kt_get(ciphername);
> +bool cipher = cipher_valid(ciphername);
>
>  /* Empty cipher is fine */
>  if (!cipher)
> @@ -80,7 +80,7 @@ test_translate_cipher(const char *ciphername, const char 
> *openvpn_name)
>  return;
>  }
>
> -const char *kt_name = cipher_kt_name(cipher);
> +const char *kt_name = cipher_kt_name(ciphername);
>
>  assert_string_equal(kt_name, openvpn_name);
>  }
> diff --git a/tests/unit_tests/openvpn/test_ncp.c 
> b/tests/unit_tests/openvpn/test_ncp.c
> index 6702133ad..92e7ce936 100644
> --- a/tests/unit_tests/openvpn/test_ncp.c
> +++ b/tests/unit_tests/openvpn/test_ncp.c
> @@ -59,8 +59,8 @@ static void
>  test_check_ncp_ciphers_list(void **state)
>  {
>  struct gc_arena gc = gc_new();
> -bool have_chacha = cipher_kt_get("CHACHA20-POLY1305");
> -bool have_blowfish = cipher_kt_get("BF-CBC");
> +bool have_chacha = cipher_valid("CHACHA20-POLY1305");
> +bool have_blowfish = cipher_valid("BF-CBC");
>
>  assert_string_equal(mutate_ncp_cipher_list("none", ), "none");
>  assert_string_equal(mutate_ncp_cipher_list("AES-256-GCM:none", ),
> @@ -100,7 +100,7 @@ test_check_ncp_ciphers_list(void **state)
>
>  /* For testing that with OpenSSL 1.1.0+ that also accepts ciphers in
>   * a different spelling the normalised cipher output is the same */
> -bool have_chacha_mixed_case = cipher_kt_get("ChaCha20-Poly1305");
> +bool have_chacha_mixed_case = cipher_valid("ChaCha20-Poly1305");
>  if (have_chacha_mixed_case)
>  {
>  
> assert_string_equal(mutate_ncp_cipher_list("AES-128-CBC:ChaCha20-Poly1305", 
> ),

Mixed use of TYPE* x and TYPE *x in a number of places. We prefer TYPE
*x, though I wont insist.

The rest looks good though I did not test.

Selva


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH applied] Re: Load OpenSSL config on Windows from trusted location

2021-11-24 Thread Selva Nair
Hi,

On Wed, Nov 24, 2021 at 9:28 AM Lev Stipakov  wrote:

> Do we need this fix in openvpn-gui? It only (?) uses openssl to change
> private key password, could this functionality be affected by config?
>

I do not know.. We do not call any functions that would lead to a config
loading, so probably not required. Automatic crypto initialization does not
load the config, nor does an explicit call to OPENSSL_init_crypto() unless
instructed to. OPENSSL_init_ssl() loads the config unless explicitly
disabled, but we do not use it in the GUI.

However, to be on the safe side, we could set these env vars if not already
set by the user.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH applied] Re: Load OpenSSL config on Windows from trusted location

2021-11-24 Thread Selva Nair
Hi

On Wed, Nov 24, 2021 at 5:06 AM Gert Doering  wrote:

> Your patch has been applied to the master and release/2.5 branch
> (I consider this a bugfix since the "do not load config!" CVE patch
> unintendedly broke functionality for people)
>

What would be a good location in the man page where we can document this.
These are not env vars we natively support so putting it under a section
named "ENVIRONMENT VARIABLES" does not seem right. Also we already have a
section with that name which refer to env vars we export to scripts.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v4] Load OpenSSL config on Windows from trusted location

2021-11-23 Thread Selva Nair
va_list arglist;
> -int len = -1;
> -if (size > 0)
> -{
> -va_start(arglist, format);
> -len = vswprintf(str, size, format, arglist);
> -va_end(arglist);
> -str[size - 1] = L'\0';
> -}
> -return (len >= 0 && len < size);
> -}
> -#endif
> -
>  /*
>   * write a string to the end of a buffer that was
>   * truncated by buf_printf
> diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
> index c9dc9d0a..ef520928 100644
> --- a/src/openvpn/crypto_openssl.c
> +++ b/src/openvpn/crypto_openssl.c
> @@ -154,13 +154,11 @@ crypto_init_lib_engine(const char *engine_name)
>  void
>  crypto_init_lib(void)
>  {
> -#ifndef _WIN32
>  #if (OPENSSL_VERSION_NUMBER >= 0x1010L)
>  OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
>  #else
>  OPENSSL_config(NULL);
>  #endif
> -#endif /* _WIN32 */
>  /*
>   * If you build the OpenSSL library and OpenVPN with
>   * CRYPTO_MDEBUG, you will get a listing of OpenSSL
> diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c
> index 6cff17b2..ee4d3f66 100644
> --- a/src/openvpn/win32.c
> +++ b/src/openvpn/win32.c
> @@ -101,6 +101,12 @@ struct semaphore netcmd_semaphore; /* GLOBAL */
>   */
>  static char *win_sys_path = NULL; /* GLOBAL */
>
> +/**
> + * Set OpenSSL environment variables to a safe directory
> + */
> +static void
> +set_openssl_env_vars();
> +
>  void
>  init_win32(void)
>  {
> @@ -110,6 +116,8 @@ init_win32(void)
>  }
>  window_title_clear(_title);
>  win32_signal_clear(_signal);
> +
> +set_openssl_env_vars();
>  }
>
>  void
> @@ -1509,4 +1517,84 @@ send_msg_iservice(HANDLE pipe, const void *data,
> size_t size,
>  return ret;
>  }
>
> +bool
> +openvpn_swprintf(wchar_t* const str, const size_t size, const wchar_t*
> const format, ...)
> +{
> +va_list arglist;
> +int len = -1;
> +if (size > 0)
> +{
> +va_start(arglist, format);
> +len = vswprintf(str, size, format, arglist);
> +va_end(arglist);
> +str[size - 1] = L'\0';
> +}
> +return (len >= 0 && len < size);
> +}
> +
> +static BOOL
> +get_install_path(WCHAR *path, DWORD size)
> +{
> +WCHAR reg_path[256];
> +HKEY key;
> +BOOL res = FALSE;
> +openvpn_swprintf(reg_path, _countof(reg_path), L"SOFTWARE\\"
> PACKAGE_NAME);

+
> +LONG status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0,
> KEY_READ, );
> +if (status != ERROR_SUCCESS)
> +{
> +return res;
> +}
> +
> +/* The default value of REG_KEY is the install path */
> +status = RegGetValueW(key, NULL, NULL, RRF_RT_REG_SZ, NULL,
> (LPBYTE)path, );
> +res = status == ERROR_SUCCESS;
> +
> +RegCloseKey(key);
> +
> +return res;
> +}
> +
> +static void
> +set_openssl_env_vars()
> +{
> +const WCHAR* ssl_fallback_dir = L"C:\\Windows\\System32";
> +
> +WCHAR install_path[MAX_PATH] = { 0 };
> +if (!get_install_path(install_path, _countof(install_path)))
> +{
> +/* if we cannot find installation path from the registry,
> + * use Windows directory as a fallback
> + */
> +openvpn_swprintf(install_path, _countof(install_path), L"%ls",
> ssl_fallback_dir);
> +}
> +
> +if ((install_path[wcslen(install_path) - 1]) == L'\\')
> +{
> +install_path[wcslen(install_path) - 1] = L'\0';
> +}
> +
> +static struct {
> +WCHAR* name;
> +WCHAR* value;
> +} ossl_env[] = {
> +{L"OPENSSL_CONF", L"openssl.cnf"},
> +{L"OPENSSL_ENGINES", L"engines"},
> +{L"OPENSSL_MODULES", L"modules"}
> +};
>

As you defined this inside the function, it doesn't have to be static.
Also, name and value could be const. Our preferred style is "TYPE *val",
not the "TYPE* val" used here and elsewhere in the patch. Neither are worth
a v5, IMO.


> +
> +for (size_t i = 0; i < SIZE(ossl_env); ++i)
> +{
> +size_t size = 0;
> +
> +_wgetenv_s(, NULL, 0, ossl_env[i].name);
> +if (size == 0)
> +{
> +WCHAR val[MAX_PATH] = {0};
> +openvpn_swprintf(val, _countof(val), L"%ls\\ssl\\%ls",
> install_path, ossl_env[i].value);
> +_wputenv_s(ossl_env[i].name, val);
> +}
> +}
> +}
> +
>  #endif /* ifdef _WIN32 */
> diff --git a/src/openvpn/win32.h b/src/openvpn/win32.h
> index 5d3371a0..4a992d91 100644
> --- a/src/openvpn/win32.h
> +++ b/src/openvpn/win32.h
> @@ -327,7 +327,13 @@ bool send_msg_iservice(HANDLE pipe, const void *data,
> size_t size,
>  int
>  openvpn_execve(const struct argv *a, const struct env_set *es, const
> unsigned int flags);
>
> -bool impersonate_as_system();
> +/*
> + * openvpn_swprintf() is currently only used by Windows code paths
> + * and when enabled for all platforms it will currently break older
> + * OpenBSD versions lacking vswprintf(3) support in their libc.
> + */
> +bool
> +openvpn_swprintf(wchar_t* const str, const size_t size, const wchar_t*
> const format, ...);


Now there is a duplicate declaration in buffer.h which could be removed.
Multiple declarations is not an error, so let it be...


>  #endif /* ifndef OPENVPN_WIN32_H */
>  #endif /* ifdef _WIN32 */
>

Acked-by: Selva Nair 
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v3] Load OpenSSL config on Windows from trusted location

2021-11-23 Thread Selva Nair
Hi,

On Tue, Nov 23, 2021 at 1:37 PM Lev Stipakov  wrote:

> I don't have a setup to properly test it, like actually loading the
> config - I only checked that the openvpn.exe attempted to access
> openssl.cnf at the correct location.
>
> If someone wants to test - binary artifacts could be found here:
> https://github.com/lstipakov/openvpn/actions/runs/1496114596


>
> I could also do testing if someone educates me how :)
>

Try using an openssl.cnf like the one below which restricts signature
algorithms to a some non-PSS schemes. Change that line to restrict them
further or comment out to use defaults: not including PSS will force
non-PSS signature with TLS 1.2 even with OpenSSL 1.1.1 server. And will
break TLS 1.3 negotiation. Removing ECC signatures and using an EC key
certificate will break the connection etc..

#
# OpenSSL configuration file to restrict siglags during handshake
#
openssl_conf = default_conf

[default_conf]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
#MinProtocol = TLSv1.2
#CipherString = DEFAULT@SECLEVEL=0
SignatureAlgorithms =
RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:RSA+SHA1:ECDSA+SHA1
# possible values
# PKCS1:  rsa_pkcs1_sha256:rsa_pkcs1_sha384:rsa_pkcs1_sha512
# ECDSA:
ecdsa_secp256r1_sha256:ecdsa_secp384r1_sha384:ecdsa_secp521r1_sha512
# PSS with rsa encryption public key
rsa_pss_rsae_sha256:rsa_pss_rsae_sha384:rsa_pss_rsae_sha512
# EdDSA :ed25519:ed448
# PSS with PSS public key:
rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512
# Legacy rsa_pkcs1_sha1:ecdsa_sha1
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v3] Load OpenSSL config on Windows from trusted location

2021-11-23 Thread Selva Nair
On Tue, Nov 23, 2021 at 1:46 PM Gert Doering  wrote:

> Hi,
>
> On Fri, Nov 19, 2021 at 02:53:06AM +0200, Lev Stipakov wrote:
> > +if ((install_path[wcslen(install_path) - 1]) == L'\\')
> > +{
> > +install_path[wcslen(install_path) - 1] = L'\0';
> > +}
> > +
> > +WCHAR openssl_cnf[MAX_PATH] = {0};
> > +WCHAR openssl_engines[MAX_PATH] = {0};
> > +WCHAR openssl_modules[MAX_PATH] = {0};
> > +
> > +openvpn_swprintf(openssl_cnf, _countof(install_path),
> > +L"OPENSSL_CONF=%ls\\ssl\\openssl.cnf", install_path);
>
> This needs to be _countof(openssl_cnf) - even if they are the same
> today, they might not be tomorrow.
>
> While at it, I wonder if it is more orderly to move the swprintf()
> calls in the "if NULL" clause now...  like this:
>
>if (_wgetenv(L"OPENSSL_CONF") == NULL)
>{
>WCHAR openssl_cnf[MAX_PATH] = {0};
>
>openvpn_swprintf(openssl_cnf, _countof(openssl_cnf),
>L"OPENSSL_CONF=%ls\\ssl\\openssl.cnf", install_path);
>_wputenv(openssl_cnf);
>}
>
> (I would not have brought this up for a v4, but the _countof() needs
> to be fixed anyway)
>

If you are doing a v4 you may want to consider:

static struct {
   wchar_t *name;
   wchar_t *value;
} ossl_env[] = {{L"OPENSSL_CNF", L"openssl.cnf"},
{"OPENSSL_ENGINES", L"engines"},
{..}};

and use a loop. Less local arrays, easy to add more to the env zoo later
etc..

Just saying --- I'm okay with the current style too.


> Regarding Selva's comment on the scope of the memory passed to _wputenv(),
> I checked MS documentation, and it does not say anything.
>

MS docs say _putenv is their implementation of POSIX putenv but the latter
does imply the pointer supplied by the user should be used as is. Anyway,
if it works with automatics, good for us.


>
> OTOH, it points to _wputenv_s(varname,string) which might be worth
> considering...
>

+1 to that especially if MSVC is planning to deprecate _wputenv as they
have already done for a  host of other such functions.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v2] Load OpenSSL config on Windows from trusted location

2021-11-23 Thread Selva Nair
   va_list arglist;
> +int len = -1;
> +if (size > 0)
> +{
> +va_start(arglist, format);
> +len = vswprintf(str, size, format, arglist);
> +va_end(arglist);
> +str[size - 1] = L'\0';
> +}
> +return (len >= 0 && len < size);
> +}
> +
> +static BOOL
> +get_install_path(WCHAR *path, DWORD size)
> +{
> +WCHAR reg_path[256];
> +HKEY key;
> +BOOL res = FALSE;
> +openvpn_swprintf(reg_path, _countof(reg_path), L"SOFTWARE\\"
> PACKAGE_NAME);
>

Does this string concatenation like L"foo" "bar" work correctly on MSVC? I
know it works on mingw, but in the past with the GUI resources we had run
into issues with such usage -- iirc, MSVC wanted L"foo" L"bar".


> +
> +LONG status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0,
> KEY_READ, );
> +if (status != ERROR_SUCCESS)
> +{
> +return res;
> +}
> +
> +/* The default value of REG_KEY is the install path */
> +status = RegGetValueW(key, NULL, NULL, RRF_RT_REG_SZ, NULL,
> (LPBYTE)path, );
> +res = status == ERROR_SUCCESS;
> +
> +RegCloseKey(key);
> +
> +return res;
> +}
> +
> +static void
> +set_openssl_env_vars()
> +{
> +const WCHAR* ssl_fallback_dir = L"C:\\Windows\\System32\\";
> +
> +WCHAR install_path[MAX_PATH] = { 0 };
> +if (!get_install_path(install_path, _countof(install_path)))
> +{
> +/* if we cannot find installation path from the registry,
> + * use Windows directory as a fallback
> + */
> +openvpn_swprintf(install_path, _countof(install_path), L"%ls",
> ssl_fallback_dir);
> +}
>

Is this registry value guaranteed to end with the directory separator "\\"?
Should we check it? If so, it may be easier to strip it here and add in the
format with no ending "\\" in the default above.


> +
> +WCHAR openssl_cnf[MAX_PATH] = {0};
> +WCHAR openssl_engines[MAX_PATH] = {0};
> +WCHAR openssl_modules[MAX_PATH] = {0};
>

On linux one needs strings on the heap or const strings for putenv() as it
does not make a copy unlike setenv (with some exceptions).  Does _wputenv
on Windows behave differently? Do local variables work?


> +
> +openvpn_swprintf(openssl_cnf, _countof(install_path),
> +L"OPENSSL_CONF=%lsssl\\openssl.cnf", install_path);
> +openvpn_swprintf(openssl_engines, _countof(openssl_engines),
> +L"OPENSSL_ENGINES=%lsssl\\engines", install_path);
> +openvpn_swprintf(openssl_modules, _countof(openssl_modules),
> +L"OPENSSL_MODULES=%lsssl\\modules", install_path);
> +
> +_wputenv(openssl_cnf);
> +_wputenv(openssl_engines);
> +_wputenv(openssl_modules);
>

I think we should set these only if not already set. Otherwise the user has
no way of overriding these locations which is the original purpose of env
vars.


> +}
> +
>  #endif /* ifdef _WIN32 */
> diff --git a/src/openvpn/win32.h b/src/openvpn/win32.h
> index 5d3371a0..4a992d91 100644
> --- a/src/openvpn/win32.h
> +++ b/src/openvpn/win32.h
> @@ -327,7 +327,13 @@ bool send_msg_iservice(HANDLE pipe, const void *data,
> size_t size,
>  int
>  openvpn_execve(const struct argv *a, const struct env_set *es, const
> unsigned int flags);
>
> -bool impersonate_as_system();
> +/*
> + * openvpn_swprintf() is currently only used by Windows code paths
> + * and when enabled for all platforms it will currently break older
> + * OpenBSD versions lacking vswprintf(3) support in their libc.
> + */
> +bool
> +openvpn_swprintf(wchar_t* const str, const size_t size, const wchar_t*
> const format, ...);
>
>  #endif /* ifndef OPENVPN_WIN32_H */
>  #endif /* ifdef _WIN32 */
> --


Commit message says this brings back config loading but the config loading
in crypto_openssl.c stays disabled for Windows. An oversight?

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] OpenSSL build on Windows: OPENSSLDIR and MODULESDIR

2021-11-22 Thread Selva Nair
On Mon, Nov 22, 2021 at 4:37 PM Gert Doering  wrote:

> Hi,
>
> On Mon, Nov 22, 2021 at 04:33:36PM -0500, Selva Nair wrote:
> > I think setting env vars would give us extra protection as we can detect
> > the actual location of Program Files or executable's path at run time.
>
> Indeed.
>
> (Also, the PR isn't exactly proceeding smoothly... no idea why the
> vcpkg maintainer does not want to see why Lev's PR is an improvement
> of the situation)
>

I didn't realize there is a pushback for the patch..May be he needs to see
https://github.com/openssl/openssl/issues/9520,
CVE-2019-5443 <https://nvd.nist.gov/vuln/detail/CVE-2019-5443> and our own
CVE?

I have a patch setting OPENSSL_CONF etc using SetEnvironmentVariableW() but
it needs more testing especially for OPENSSL_ENGINES and OPENSSL_MODULES in
3.0.
Is _putenv preferred?

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] OpenSSL build on Windows: OPENSSLDIR and MODULESDIR

2021-11-22 Thread Selva Nair
Hi,

On Mon, Nov 22, 2021 at 3:27 PM Lev Stipakov  wrote:

> Hi,
>
> I added
>
> _putenv("OPENSSL_CONF=c:\\Temp\\lol.conf");
>
> to openvpn_main() and see
>
> 22:01:38,9512311 openvpn.exe 27668 CreateFile C:\Temp\lol.conf
> NAME NOT FOUND
>
> in procmon. So would it be enough to set config/engines/modules paths
> as env variables for openvpn and gui? OTOH we also ship openssl.exe,
> which is used by easyrsa?
>

I would be a bit wary of distributing OpenSSL libs with "unsafe" built-in
paths, so probably we may still need to get some good defaults in the
build. My concern is that even C:\Program Files\...\ is probably not safe
enough -- I see that curl developers had the same thought.
https://github.com/openssl/openssl/issues/9520#issuecomment-913562621
Not sure how they solved it. I think they cross-build using mingw which is
much easier to handle.

I think setting env vars would give us extra protection as we can detect
the actual location of Program Files or executable's path at run time.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] OpenSSL build on Windows: OPENSSLDIR and MODULESDIR

2021-11-22 Thread Selva Nair
Hi,

On Mon, Nov 22, 2021 at 12:20 PM Lev Stipakov  wrote:

> I added a commit to vcpkg/openssl PR
> (https://github.com/microsoft/vcpkg/pull/21540) which gives an option
> to customize ENGINESDIR. Unfortunately openssl doesn't make it easy -
> ENGINESDIR is built based on --prefix, which is set to vcpkg build
> dir. The prefix cannot be set to something like C:\SSL, because in
> this case vcpkg build would require an elevated prompt. So I had to
> patch the makefile template. Let's see if there are less hacky ways to
> do it.
>

A common practice for locally installing to a private path for development
would be to do a "prefix relocation" using DESTDIR:

make DESTDIR=/home/selva/openssl-pkg/ install

which will preserve the search paths compiled into the library. This will
work for cross-compile on linux even with drive letters in prefix, though
awkward.  But such an approach cannot work on Windows as "C:" cannot be
embedded in Windows paths.

A hack could be to use paths without a drive letter: like prefix =
"/Program Files/OpenVPN/" etc. and then use DESTDIR to relocate for the
development installation. That relies on the Windows behaviour that paths
starting with "/" resolve to "C:/"  and depends on the value of "current
drive" which is probably reliable.

Otherwise patching as you propose may be the only way..

That said, how safe is this use of "C:/Program files/foo-bar" itself? Could
it be vulnerable in localized Windows -- e.g., "C:/Program Files/" may not
exist in some language versions and any user could then create one. If so,
we may have to set "C:/Windows/System32/" or some such path as OPENSSLDIR,
ENGINESDIR and MODULESDIR. It's unfortunate that OpenSSL folks decided to
use hard-coded values in the library for config location and dll search
paths.

Given these difficulties, shall we (also) set env vars in OpenVPN.exe on
startup so that OpenSSL config file and search paths will point to safe
locations determined at run time (only if not already set by user) --
needed only for Windows as we do not distribute OpenSSL for other
platforms. OpenSSL docs say what env vars are used to override built-in
paths, I'll do some tests to be sure.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] OpenSSL build on Windows: OPENSSLDIR and MODULESDIR

2021-11-19 Thread Selva Nair
Hi,

On Fri, Nov 19, 2021 at 3:04 PM  wrote:

> Ok, my idea was to fix only config loading dir. Apparently this is not
> enough, so I’ll look into ENGINESDIR too.


What we need is a proper build that can be safely distributed. Whatever
that takes. My understanding is that if we have to get with prefix and
OPENSSLDIR set to values recommended by OpenSSL on Windows or something
appropriate for our own use and still safe.

Default location of configs, engine dlls, modules etc. depend on those two
definitions -- we can't leave them at arbitrary values that are not write
protected or unusable.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] OpenSSL build on Windows: OPENSSLDIR and MODULESDIR

2021-11-19 Thread Selva Nair
Hi

On Fri, Nov 19, 2021 at 11:16 AM Lev Stipakov  wrote:

> Hi,
>
> Here is what output of openssl.exe built with abovementioned patch on
> my machine:
>
>
> c:\Users\lev\Projects\vcpkg\packages\openssl_x64-windows-ovpn\tools\openssl>openssl.exe
> version -a
> OpenSSL 1.1.1l  24 Aug 2021
> built on: Fri Nov 19 09:43:38 2021 UTC
> platform: VC-WIN64A
> options:  bn(64,64) rc4(16x,int) des(long) idea(int) blowfish(ptr)
> compiler: cl /Zi /Fdossl_static.pdb /Gs0 /GF /Gy /MD /W3 /wd4090
> /nologo /O2 -utf-8 -FS -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ
> -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5
> -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM
> -DKECCAK1600_ASM -DRC4_ASM -DMD5_ASM -DAESNI_ASM -DVPAES_ASM
> -DGHASH_ASM -DECP_NISTZ256_ASM -DX25519_ASM -DPOLY1305_ASM
> OPENSSLDIR: "C:\Program Files\OpenVPN\ssl"
> ENGINESDIR:
> "C:\Users\lev\Projects\vcpkg\packages\openssl_x64-windows-ovpn\lib\engines-1_1"
>

That seems to indicate that the prefix is not set properly. See NOTES.WIN
or NOTES.WINDOWS in OpenSSL source tree for default locations chosen in
MSVC build which are safe. I do not have Windows packaging experience, so
I'm not sure why vcpkg folks are using the working directory for setting
these paths and not following OpenSSL installation docs.


> Seeding source: os-specific
>
> ENGINESDIR looks good, no? Is it something we use?
>

I think that's where engine dlls will get loaded from when specified as a
relative path or name. We  allow loading of engines via the "--engine"
option.

Also I guess MODULESDIR in 3.0 build will point to C:\Users\ which is
not acceptable. Provider names or dlls that the user specifies using our
new "--providers" option will get loaded from there. Also we have to
distribute the dll for the legacy provider which will go into the
MODULESDIR.

Users can override these using env vars but the built-in values should
point to read-only locations.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] OpenSSL build on Windows: OPENSSLDIR and MODULESDIR

2021-11-19 Thread Selva Nair
Hi,

On Fri, Nov 19, 2021 at 6:43 AM Lev Stipakov  wrote:

> Hi,
>
> I've submitted PR to vcpkg's openssl port:
> https://github.com/microsoft/vcpkg/pull/21540
>
> With that PR merged, we could specify proper location of config like
> this (extracted from custom triplet):
>
>   set(OPENSSL_OPENSSLDIR "c:\\Program Files\\OpenVPN\\ssl")
>   set(OPENSSL_NO_INSTALL_SSLDIRS ON)
>

I don't know about vcpkg, but having a way to override prefix and
OPENSSLDIR should help us.

What does the resulting executable when run as  "openssl.exe version -a"?
output for OPENSSLDIR, ENGINESDIR and MODULESDIR? The last one is for
OpenSSL 3+ only and indicates the default location of provider modules like
"legacy".

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] Use network address for emulated DHCP server as a default

2021-11-12 Thread Selva Nair
>
> How about we apply my original patch (0 for /28 and -1 for the rest)
> to 2.5 and this one to master?

I do not see the logic behind that. If there are any platforms where 0
(network address) is not acceptable, it's unlikely to work for /30 as
well. /31 is special, /30 is not. And, based on your tests 0 does work
on all platforms we support. Same was my conclusion the last time I
checked.

So I would also vote for the current patch as is.

Selva


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v5] [OSSL 3.0] Allow loading of non default providers

2021-11-11 Thread Selva Nair
On Thu, Nov 11, 2021 at 4:09 PM Gert Doering  wrote:
>
> Hi,
>
> On Thu, Nov 11, 2021 at 08:20:51PM +0100, Arne Schwabe wrote:
> > diff --git a/src/openvpn/options.c b/src/openvpn/options.c
> > index b5d65d293..b1f9473dc 100644
> > --- a/src/openvpn/options.c
> > +++ b/src/openvpn/options.c
> > @@ -8157,6 +8158,13 @@ add_option(struct options *options,
> >  options->engine = "auto";
> >  }
> >  }
> > +else if (streq(p[0], "providers") && p[1])
> > +{
> > +for (size_t j = 1; j < MAX_PARMS && p[j] != NULL;j++)
> > +{
> > +options->providers.names[j] = p[j];
> > +}
> > +}
> >  #endif /* ENABLE_CRYPTO_MBEDTLS */
>
> This seems to be in an #ifndef ENABLE_CRYPTO_MBEDTLS block, which
> means an mbedTLS build won't understand the option "--providers"
> (but --help shows it, and there's a "mbed TLS provider functionality
> is not available" patch in crypto_mbedtls.c...)

hmm.. obviously I did not build with mbed TLS nor think about it. Some
empty functions in crypto_mbedtls.c are still required as the load and
unload are unconditionally called.

Moving this out of the #ifndef will make --help consistent with  the
option, but at the same time it's misleading to include this in --help
for mbedTLS builds: the user will get a warning if the option is used.
I think we should add this option to --help only for OpenSSL. And,
while parsing, add provider names to the list only for OpenSSL, show a
warning for mbedTLS. That way the list will remain empty for mbedTLS.
I'm supposing that we do not want --provider to become a M_FATAL error
in mbedTLS builds.

Whether the msg(WARN,..) in crypto_mbedtls.c are removed or not is a
matter of taste -- they will never get executed if not parsed here.

Selva


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] Summary of the community meeting (10th November 2021)

2021-11-11 Thread Selva Nair
Quoting from meeting log:

> (15:50:52) cron2: and the ERR_BUF_SIZE (21/21) is missing as well...

This is not really a missing piece in the OpenSSl 3.0/deprecation
patch set as the buffer size increase is not a necessity yet. The need
for a larger buffer arises when we start sending undigested messages
for signature to the management client: a feature planned as a part of
the external-key provider patches to make PSS signature generation
easier on Android.

So, right now it's like a cart before the horse, though it could be
argued as a refactoring/cleanup as well -- unrelated to OpenSSL 3.0
though.

Selva


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v5] [OSSL 3.0] Allow loading of non default providers

2021-11-11 Thread Selva Nair
--reneg-bytes n : Renegotiate data chan. key after n bytes sent and
> recvd.\n"
> @@ -8157,6 +8158,13 @@ add_option(struct options *options,
>  options->engine = "auto";
>  }
>  }
> +else if (streq(p[0], "providers") && p[1])
> +{
> +for (size_t j = 1; j < MAX_PARMS && p[j] != NULL;j++)
> +{
> +options->providers.names[j] = p[j];
> +}
> +}
>  #endif /* ENABLE_CRYPTO_MBEDTLS */
>  #ifdef ENABLE_PREDICTION_RESISTANCE
>  else if (streq(p[0], "use-prediction-resistance") && !p[1])
> diff --git a/src/openvpn/options.h b/src/openvpn/options.h
> index 20b34ed4e..d4f41cd71 100644
> --- a/src/openvpn/options.h
> +++ b/src/openvpn/options.h
> @@ -179,6 +179,14 @@ struct remote_list
>  struct remote_entry *array[CONNECTION_LIST_SIZE];
>  };
>
> +struct provider_list
> +{
> +/* Names of the providers */
> +const char *names[MAX_PARMS];
> +/* Pointers to the loaded providers to unload them */
> +provider_t *providers[MAX_PARMS];
> +};
> +
>  enum vlan_acceptable_frames
>  {
>  VLAN_ONLY_TAGGED,
> @@ -519,6 +527,7 @@ struct options
>  const char *ncp_ciphers;
>  const char *authname;
>  const char *engine;
> +struct provider_list providers;
>  bool replay;
>  bool mute_replay_warnings;
>  int replay_window;
> --
> 2.33.0
>

Acked-by: Selva Nair 

Request for nit-fix during commit:
In the newly added paragraph in Changes.rst please change
``--provider`` to ``--providers``

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v4] [OSSL 3.0] Allow loading of non default providers

2021-11-11 Thread Selva Nair
>
> diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
> index cc1d62210..ab38d6e5c 100644
> --- a/src/openvpn/crypto_openssl.c
> +++ b/src/openvpn/crypto_openssl.c
> @@ -54,6 +54,9 @@
>  #if (OPENSSL_VERSION_NUMBER >= 0x1010L) &&
> !defined(LIBRESSL_VERSION_NUMBER)
>  #include 
>  #endif
> +#if OPENSSL_VERSION_NUMBER >= 0x3000L
> +#include 
> +#endif
>
>  #if defined(_WIN32) && defined(OPENSSL_NO_EC)
>  #error Windows build with OPENSSL_NO_EC: disabling EC key is not
> supported.
> @@ -149,6 +152,33 @@ crypto_init_lib_engine(const char *engine_name)
>  #endif
>  }
>
> +provider_t *
> +crypto_load_provider(const char *provider)
> +{
> +#if OPENSSL_VERSION_NUMBER >= 0x3000L
> +/* Load providers into the default (NULL) library context */
> +OSSL_PROVIDER* prov = OSSL_PROVIDER_load(NULL, provider);
> +if (!prov)
> +{
> +crypto_msg(M_FATAL, "failed to load provider '%s'", provider);
> +}
> +return prov;
> +#else  /* OPENSSL_VERSION_NUMBER >= 0x3000L */
> +msg(M_WARN, "Note: OpenSSL hardware crypto engine functionality is
> not available");
>

"hardware crypto engine" --> "provider"


> +return NULL;
> +#endif
> +}
> +
> +void crypto_unload_provider(const char* provname, provider_t *provider)
> +{
> +#if OPENSSL_VERSION_NUMBER >= 0x3000L
> +if (!OSSL_PROVIDER_unload(provider))
> +{
> +crypto_msg(M_FATAL, "failed to undload provider '%s'", provname);
>

"undload" --> "unload"


> +}
> +#endif
> +}
> +
>  /*
>   *
>   * Functions related to the core crypto library
> diff --git a/src/openvpn/crypto_openssl.h b/src/openvpn/crypto_openssl.h
> index e540a76b9..446f08508 100644
> --- a/src/openvpn/crypto_openssl.h
> +++ b/src/openvpn/crypto_openssl.h
> @@ -33,6 +33,10 @@
>  #include 
>  #include 
>  #include 
> +#if OPENSSL_VERSION_NUMBER >= 0x3000L
> +#include 
> +#endif
> +
>
>  /** Generic cipher key type %context. */
>  typedef EVP_CIPHER cipher_kt_t;
> @@ -49,12 +53,17 @@ typedef EVP_MD_CTX md_ctx_t;
>  /** Generic HMAC %context. */
>  #if OPENSSL_VERSION_NUMBER < 0x3000L
>  typedef HMAC_CTX hmac_ctx_t;
> +
> +/* Use a dummy type for the provider */
> +typedef void provider_t;
>  #else
>  typedef struct {
>  OSSL_PARAM params[3];
>  uint8_t key[EVP_MAX_KEY_LENGTH];
>  EVP_MAC_CTX *ctx;
>  } hmac_ctx_t;
> +
> +typedef OSSL_PROVIDER provider_t;
>  #endif
>
>  /** Maximum length of an IV */
> diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c
> index da06f59c2..095d448b0 100644
> --- a/src/openvpn/openvpn.c
> +++ b/src/openvpn/openvpn.c
> @@ -112,10 +112,23 @@ void init_early(struct context *c)
>  /* init verbosity and mute levels */
>  init_verb_mute(c, IVM_LEVEL_1);
>
> +/* Initialise OpenVPN provider, this needs to be initialised this
>

"OpenVPN provider" --> "OpenSSL provider"


> +* early since option post-processing and also openssl info
> +* printing depends on it */
> +for (int j=1; j < MAX_PARMS && c->options.providers.names[j]; j++)
> +{
> +c->options.providers.providers[j] =
> +crypto_load_provider(c->options.providers.names[j]);
> +}
>  }
>
>  static void uninit_early(struct context *c)
>  {
> +for (int j=1; j < MAX_PARMS && c->options.providers.providers[j]; j++)
> +{
> +crypto_unload_provider(c->options.providers.names[j],
> +   c->options.providers.providers[j]);
> +}
>  net_ctx_free(>net_ctx);
>  }
>
> diff --git a/src/openvpn/options.c b/src/openvpn/options.c
> index b5d65d293..87062d58d 100644
> --- a/src/openvpn/options.c
> +++ b/src/openvpn/options.c
> @@ -8157,6 +8157,13 @@ add_option(struct options *options,
>  options->engine = "auto";
>  }
>  }
> +else if (streq(p[0], "provider") && p[1])
>

 "providers" please


> +{
> +for (size_t j = 1; j < MAX_PARMS && p[j] != NULL;j++)
> +{
> +options->providers.names[j] = p[j];
> +}
> +}
>  #endif /* ENABLE_CRYPTO_MBEDTLS */
>  #ifdef ENABLE_PREDICTION_RESISTANCE
>  else if (streq(p[0], "use-prediction-resistance") && !p[1])
> diff --git a/src/openvpn/options.h b/src/openvpn/options.h
> index 20b34ed4e..d4f41cd71 100644
> --- a/src/openvpn/options.h
> +++ b/src/openvpn/options.h
> @@ -179,6 +179,14 @@ struct remote_list
>  struct remote_entry *array[CONNECTION_LIST_SIZE];
>  };
>
> +struct provider_list
> +{
> +/* Names of the providers */
> +const char *names[MAX_PARMS];
> +/* Pointers to the loaded providers to unload them */
> +provider_t *providers[MAX_PARMS];
> +};
> +
>  enum vlan_acceptable_frames
>  {
>  VLAN_ONLY_TAGGED,
> @@ -519,6 +527,7 @@ struct options
>  const char *ncp_ciphers;
>  const char *authname;
>  const char *engine;
> +struct provider_list providers;
>  bool replay;
>  bool mute_replay_warnings;
>  int replay_window;
>

The new option is not added to usage_message for --help and usage().

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] Use network address for emulated DHCP server as a default

2021-11-11 Thread Selva Nair
Hi

On Thu, Nov 11, 2021 at 4:41 AM Lev Stipakov  wrote:

> From: Lev Stipakov 
>
> This is the rebase of original Selva Nair's patch
> which hasn't been merged:
>
>   https://sourceforge.net/p/openvpn/mailman/message/34674818/


Yes, something I wanted 5 years ago


>
> and documentation change to reflect code changes, which
> is basically a revert of another Selva's patch (which got merged):
>
>
> https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg13387.html


That was a compromise as the offset patch got no traction..


>
>
> For subnet topology use "offset 0" as default for
> calculating DHCP server address, which makes it equal
> to the network address.
>
> There is no know reason why non-zero default offset
> is needed. Besides, offset -1 breaks subnet /30 case,
> which in some cases is pushed by OpenVPN Cloud product.
>

I could not sell this as a bugfix that time as /30 in subnet mode was not
possible with our server mode as the pool would have been empty in that
case without the patch. Also /30 in subnet mode was considered somewhat
silly.

The reason for the original -1 is probably historical -- the general "rule"
not to use network address as a source address.


>
> Signed-off-by: Lev Stipakov 
> ---
>  doc/man-sections/windows-options.rst | 2 +-
>  src/openvpn/helper.c | 4 ++--
>  src/openvpn/tun.c| 9 +
>  3 files changed, 4 insertions(+), 11 deletions(-)
>
> diff --git a/doc/man-sections/windows-options.rst
> b/doc/man-sections/windows-options.rst
> index eacb9af8..c389fbc4 100644
> --- a/doc/man-sections/windows-options.rst
> +++ b/doc/man-sections/windows-options.rst
> @@ -93,7 +93,7 @@ Windows-Specific Options
>  server to masquerade as if it were coming from the remote
> endpoint.
>
>  The optional offset parameter is an integer which is >
> :code:`-256`
> -and < :code:`256` and which defaults to -1. If offset is positive,
> +and < :code:`256` and which defaults to 0. If offset is positive,
>  the DHCP server will masquerade as the IP address at network
>  address + offset. If offset is negative, the DHCP server will
>  masquerade as the IP address at broadcast address + offset.
> diff --git a/src/openvpn/helper.c b/src/openvpn/helper.c
> index 032a71e8..4ac1cf8e 100644
> --- a/src/openvpn/helper.c
> +++ b/src/openvpn/helper.c
> @@ -237,7 +237,7 @@ helper_client_server(struct options *o)
>   * if tap OR (tun AND topology == subnet):
>   *   ifconfig 10.8.0.1 255.255.255.0
>   *   if !nopool:
> - * ifconfig-pool 10.8.0.2 10.8.0.253 255.255.255.0
> + * ifconfig-pool 10.8.0.2 10.8.0.254 255.255.255.0
>   *   push "route-gateway 10.8.0.1"
>   *   if route-gateway unset:
>   * route-gateway 10.8.0.2
> @@ -340,7 +340,7 @@ helper_client_server(struct options *o)
>  {
>  o->ifconfig_pool_defined = true;
>  o->ifconfig_pool_start = o->server_network + 2;
> -o->ifconfig_pool_end = (o->server_network |
> ~o->server_netmask) - 2;
> +o->ifconfig_pool_end = (o->server_network |
> ~o->server_netmask) - 1;
>  ifconfig_pool_verify_range(M_USAGE,
> o->ifconfig_pool_start, o->ifconfig_pool_end);
>  }
>  o->ifconfig_pool_netmask = o->server_netmask;
> diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c
> index 28f803ec..75d5eaf7 100644
> --- a/src/openvpn/tun.c
> +++ b/src/openvpn/tun.c
> @@ -6357,14 +6357,7 @@ tuntap_dhcp_mask(const struct tuntap *tt, const
> char *device_guid)
>  {
>  if (tt->topology == TOP_SUBNET)
>  {
> -if (tt->options.dhcp_masq_custom_offset)
> -{
> -ep[2] = dhcp_masq_addr(tt->local, tt->remote_netmask,
> tt->options.dhcp_masq_offset);
> -}
> -else
> -{
> -ep[2] = dhcp_masq_addr(tt->local, tt->remote_netmask, -1);
> -}
> +ep[2] = dhcp_masq_addr(tt->local, tt->remote_netmask,
> tt->options.dhcp_masq_custom_offset ? tt->options.dhcp_masq_offset : 0);
>  }
>  else
>  {
> --
> 2.23.0.windows.1
>

Looks good to me based on my recollection of testing this a long time ago
-- I have not re-tested this version of the patch.

(An ACK from me may look like an attempt to get in via the backdoor, so
resisting that..).

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] tun: improve DHCP server address calculation for small subnets

2021-11-10 Thread Selva Nair
Hi,

On Wed, Nov 10, 2021 at 6:01 AM Lev Stipakov  wrote:

> From: Lev Stipakov 
>
> When /30 subnet is pushed (like in the case of OpenVPN Cloud),
> DHCP server address is calculated to be the same as local address,
> which causes collision and therefore connection is not established.
>
> To fix that, use openvpn3 approach, which sets DHCP server
> address to a network address for small subnets
>
> Signed-off-by: Lev Stipakov 
> ---
>  src/openvpn/tun.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c
> index 28f803ec..994e3751 100644
> --- a/src/openvpn/tun.c
> +++ b/src/openvpn/tun.c
> @@ -6363,7 +6363,9 @@ tuntap_dhcp_mask(const struct tuntap *tt, const char
> *device_guid)
>  }
>  else
>  {
> -ep[2] = dhcp_masq_addr(tt->local, tt->remote_netmask, -1);
> +int prefix_len = netmask_to_netbits2(tt->adapter_netmask);
> +/* use network address as DHCP server for small subnets,
> otherwise last address before broadcast */
> +ep[2] = dhcp_masq_addr(tt->local, tt->remote_netmask,
> prefix_len < 28 ? -1 : 0);
>  }
>  }
>  else
> --


Why not just use 0 offset always? Perpetuating this dance of 0 offset in
some cases, -1 otherwise is not a way forward. Also see my patch from 2015
that never got any traction. I have lost touch with the context, so, I'm
not sure whether this addresses the same (apart from code changes) or
something related.

https://sourceforge.net/p/openvpn/mailman/openvpn-devel/thread/1449454660-20050-1-git-send-email-selva.nair%40gmail.com/#msg34674818

Also:
https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg13413.html
and other messages in that thread.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] OpenSSL build on Windows: OPENSSLDIR and MODULESDIR

2021-11-10 Thread Selva Nair
Hi,

On Sun, Nov 7, 2021 at 9:14 AM Lev Stipakov  wrote:

> Hi,
>
> We agreed during the hackathon that we are going to ship a 2.6 Windows
> client with OpenSSL 3.0. Apart from merging relevant patches, there
> are few (small) blocks:
>
>  - vcpkg hasn't yet added OpenSSL 3.0 to official repo, but there is a
> PR https://github.com/microsoft/vcpkg/pull/20428 This shouldn't be a
> problem for us, since we could just have this port in openvpn repo,
> like we do with pkcs11-helper.
>
>  - The latest release of pkcs11-helper doesn't build with openssl3,
> but things are progressing -
> https://github.com/OpenSC/pkcs11-helper/issues/42. We would also have
> to make sure that our vcpkg port for pkcs11-helper builds with
> openssl3.
>
> Once OpenSSL 3.0 support is somewhat settled, we could look into
> configuration file loading. I haven't checked vcpkg scripts, but in
> the best case scenario we won't have to do anything and just rely on
> readonly values you've mentioned.
>

While this sounds good for 2.6, can we fix this in 2.5 as well?  In mingw
cross builds our mistake was using "--openssl-dir /etc/ssl" with OpenSSL
"Configure". Not sure what we do now for MSVC builds. The default
locations are pretty decent as per NOTES.WIN in OpenSSL 1.1.1 tree.

Selva
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH v4] Refactor early initialisation and uninitialisation into methods

2021-11-05 Thread Selva Nair
Hi

On Fri, Nov 5, 2021 at 12:14 PM Arne Schwabe  wrote:

> This put the early initialisation and uninitialisation that needs to
> happen between option parsing and post processing into small methods.
>
> Signed-off-by: Arne Schwabe 
> ---
>  src/openvpn/openvpn.c | 23 ++-
>  1 file changed, 18 insertions(+), 5 deletions(-)
>
> diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c
> index 0ac961429..05b5dc2d0 100644
> --- a/src/openvpn/openvpn.c
> +++ b/src/openvpn/openvpn.c
> @@ -105,6 +105,20 @@ tunnel_point_to_point(struct context *c)
>
>  #undef PROCESS_SIGNAL_P2P
>
> +void init_early(struct context *c)
> +{
> +net_ctx_init(c, c->net_ctx);
>

hmm... this should have been >net_ctx. Can this be fixed during commit?
The rest looks good.


> +
> +/* init verbosity and mute levels */
> +init_verb_mute(c, IVM_LEVEL_1);
> +
> +}
> +
> +static void uninit_early(struct context *c)
> +{
> +net_ctx_free(>net_ctx);
> +}
> +
>
>
>  /**/
>  /**
> @@ -193,10 +207,9 @@ openvpn_main(int argc, char *argv[])
>  open_plugins(, true, OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE);
>  #endif
>
> -net_ctx_init(, _ctx);
> -
> -/* init verbosity and mute levels */
> -init_verb_mute(, IVM_LEVEL_1);
> +/* Early initialisation that need to happen before option
> + * post processing and other early startup but after parsing
> */
> +init_early();
>
>  /* set dev options */
>  init_options_dev();
> @@ -308,7 +321,7 @@ openvpn_main(int argc, char *argv[])
>  env_set_destroy(c.es);
>  uninit_options();
>  gc_reset();
> -net_ctx_free(_ctx);
> +uninit_early();
>  }
>  while (c.sig->signal_received == SIGHUP);
>  }
> --
> 2.33.0
>
>
>
> ___
> Openvpn-devel mailing list
> Openvpn-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/openvpn-devel
>
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH 0/9] A built-in OpenSSL3.0 provider for external-keys

2021-11-01 Thread Selva Nair
Hi,

OpenSSL folks have merged their "fix" in the provider interface that I was
waiting for. It will be in the 3.0.1 patch release. In the meantime, I have
opened a matching version of this patch set as a PR for OpenVPN for
comments/tests/bug-reports/nitpicks. I skipped v2 and this version is
tagged v3.

Will post the patches to the list when OpenSSL 3.0.1 is released.

On top of v1 patches this also includes handling pkcs11-id and
cryptoapicert options through the provider. Requires OpenSSL from either
the master branch (3.1.0-dev) or 3.0 branch (3.0.1-dev) post Oct. 27.

Cheers,

Selva

On Tue, Oct 5, 2021 at 12:39 PM Selva Nair  wrote:

> Hi
>
> Here is an update on this patch set to keep all in the loop.
>
> Arne discovered that my patch broke ECDH key exchange in some cases.  This
> turns out to be due to the way providers are handled in OpenSSL especially
> when used in a TLS context. It leads to the requirement that an external
> provider has to handle a wide zoo of  key operations including key exchange
> and key generation, even if all it wants to do is signing with an external
> key. Essentially something like: "you either export the key to me or be
> ready to import and handle all operations on any asymmetric key I may come
> across". We can't export as the key is in a protected storage in some
> backend,  we also do not want to do all that extra work that's not in the
> contract, and we are not good at it either.
>
> I have been engaging with OpenSSL developers on this and they realize this
> was unintended, and is a "bug/weakness" in their implementation. They are
> working on a patch to fix it at their end (
> https://github.com/openssl/openssl/pull/16725). The eventual fix is very
> likely to get backported to OpenSSL 3.0, so we have to wait.
>
> I'll submit a slightly modified v2 once their fix is finalized.
>
> Thanks,
>
> Selva
>
>>
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


<    1   2   3   4   5   6   7   8   9   10   >