[Openvpn-devel,v4,2/2] Add unit tests for engine keys

Message ID 1518303011.3072.4.camel@HansenPartnership.com
State Changes Requested
Headers show
Series add engine keys keys | expand

Commit Message

James Bottomley Feb. 10, 2018, 11:50 a.m. UTC
Testing engines is problematic, so one of the prerequisites built for
the tests is a simple openssl engine that reads a non-standard PEM
guarded key.  The test is simply can we run a client/server
configuration with the usual sample key replaced by an engine key.
The trivial engine prints out some operations and we check for these
in the log to make sure the engine was used to load the key and that
it correctly got the password.

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

---
v4: add OPENSSL_config(NULL) so debian checks will work
v3: added this patch
---
 configure.ac                                     |   2 +
 src/openvpn/crypto_openssl.c                     |   1 +
 tests/unit_tests/Makefile.am                     |   6 +-
 tests/unit_tests/engine-key/Makefile.am          |  14 ++++
 tests/unit_tests/engine-key/check_engine_keys.sh |  30 +++++++
 tests/unit_tests/engine-key/libtestengine.c      | 102 +++++++++++++++++++++++
 tests/unit_tests/engine-key/openssl.cnf          |  12 +++
 7 files changed, 166 insertions(+), 1 deletion(-)
 create mode 100644 tests/unit_tests/engine-key/Makefile.am
 create mode 100755 tests/unit_tests/engine-key/check_engine_keys.sh
 create mode 100644 tests/unit_tests/engine-key/libtestengine.c
 create mode 100644 tests/unit_tests/engine-key/openssl.cnf

Comments

Arne Schwabe Feb. 13, 2020, 7:18 a.m. UTC | #1
Am 10.02.18 um 23:50 schrieb James Bottomley:
> Testing engines is problematic, so one of the prerequisites built for
> the tests is a simple openssl engine that reads a non-standard PEM
> guarded key.  The test is simply can we run a client/server
> configuration with the usual sample key replaced by an engine key.
> The trivial engine prints out some operations and we check for these
> in the log to make sure the engine was used to load the key and that
> it correctly got the password.

This tests the openssl engine functionality in a sensible way. But I
think it is not fully ready to be commited. To get it working I needed
to do following changes on my Mac:

commit afa697cec15b4e54e720efe9de39c9b20b13c5c8 (HEAD -> review/enginekeys)
Author: Arne Schwabe <arne@rfc2549.org>
Date:   Thu Feb 13 18:13:34 2020 +0100

    foo

diff --git a/tests/unit_tests/engine-key/Makefile.am
b/tests/unit_tests/engine-key/Makefile.am
index 73921965..6d7fc9c5 100644
--- a/tests/unit_tests/engine-key/Makefile.am
+++ b/tests/unit_tests/engine-key/Makefile.am
@@ -10,4 +10,6 @@ TESTS_ENVIRONMENT = srcdir="$(abs_srcdir)"; \
 TESTS = check_engine_keys.sh

 libtestengine_la_SOURCES = libtestengine.c
-libtestengine_la_LDFLAGS = -rpath /lib -avoid-version
+libtestengine_la_LDFLAGS = @TEST_LDFLAGS@  -rpath /lib
+libtestengine_la_CFLAGS  = @TEST_CFLAGS@ -I$(openvpn_srcdir)
-I$(compat_srcdir)
+
diff --git a/tests/unit_tests/engine-key/libtestengine.c
b/tests/unit_tests/engine-key/libtestengine.c
index fa7f5de1..46ec1e33 100644
--- a/tests/unit_tests/engine-key/libtestengine.c
+++ b/tests/unit_tests/engine-key/libtestengine.c
@@ -30,7 +30,6 @@ static EVP_PKEY *engine_load_key(ENGINE *e, const char
*key_id,
        PKCS8_PRIV_KEY_INFO *p8inf;
        UI *ui;
        char auth[256];
-       int len;

        fprintf(stderr, "ENGINE: engine_load_key called\n");

diff --git a/tests/unit_tests/engine-key/openssl.cnf
b/tests/unit_tests/engine-key/openssl.cnf
index 53200c46..e9513a92 100644
--- a/tests/unit_tests/engine-key/openssl.cnf
+++ b/tests/unit_tests/engine-key/openssl.cnf
@@ -9,4 +9,4 @@ engines         = engines_section
 testengine     = testengine_section

 [testengine_section]
-dynamic_path   = $ENV::srcdir/.libs/libtestengine.so
+dynamic_path   = $ENV::srcdir/.libs/libtestengine.dylib
James Bottomley Feb. 14, 2020, 1:38 a.m. UTC | #2
On Thu, 2020-02-13 at 19:18 +0100, Arne Schwabe wrote:
> Am 10.02.18 um 23:50 schrieb James Bottomley:
> > Testing engines is problematic, so one of the prerequisites built
> > for the tests is a simple openssl engine that reads a non-standard
> > PEM guarded key.  The test is simply can we run a client/server
> > configuration with the usual sample key replaced by an engine key.
> > The trivial engine prints out some operations and we check for
> > these in the log to make sure the engine was used to load the key
> > and that it correctly got the password.
> 
> This tests the openssl engine functionality in a sensible way. But I
> think it is not fully ready to be commited. To get it working I
> needed to do following changes on my Mac:

That could be ... I only have a linux box to try this out on.

> commit afa697cec15b4e54e720efe9de39c9b20b13c5c8 (HEAD ->
> review/enginekeys)
> Author: Arne Schwabe <arne@rfc2549.org>
> Date:   Thu Feb 13 18:13:34 2020 +0100
> 
>     foo
> 
> diff --git a/tests/unit_tests/engine-key/Makefile.am
> b/tests/unit_tests/engine-key/Makefile.am
> index 73921965..6d7fc9c5 100644
> --- a/tests/unit_tests/engine-key/Makefile.am
> +++ b/tests/unit_tests/engine-key/Makefile.am
> @@ -10,4 +10,6 @@ TESTS_ENVIRONMENT = srcdir="$(abs_srcdir)"; \
>  TESTS = check_engine_keys.sh
> 
>  libtestengine_la_SOURCES = libtestengine.c
> -libtestengine_la_LDFLAGS = -rpath /lib -avoid-version
> +libtestengine_la_LDFLAGS = @TEST_LDFLAGS@  -rpath /lib
> +libtestengine_la_CFLAGS  = @TEST_CFLAGS@ -I$(openvpn_srcdir)
> -I$(compat_srcdir)
> +
> diff --git a/tests/unit_tests/engine-key/libtestengine.c
> b/tests/unit_tests/engine-key/libtestengine.c
> index fa7f5de1..46ec1e33 100644
> --- a/tests/unit_tests/engine-key/libtestengine.c
> +++ b/tests/unit_tests/engine-key/libtestengine.c
> @@ -30,7 +30,6 @@ static EVP_PKEY *engine_load_key(ENGINE *e, const
> char
> *key_id,
>         PKCS8_PRIV_KEY_INFO *p8inf;
>         UI *ui;
>         char auth[256];
> -       int len;

the variable is certainly unused and can go.

>         fprintf(stderr, "ENGINE: engine_load_key called\n");
> 
> diff --git a/tests/unit_tests/engine-key/openssl.cnf
> b/tests/unit_tests/engine-key/openssl.cnf
> index 53200c46..e9513a92 100644
> --- a/tests/unit_tests/engine-key/openssl.cnf
> +++ b/tests/unit_tests/engine-key/openssl.cnf
> @@ -9,4 +9,4 @@ engines         = engines_section
>  testengine     = testengine_section
> 
>  [testengine_section]
> -dynamic_path   = $ENV::srcdir/.libs/libtestengine.so
> +dynamic_path   = $ENV::srcdir/.libs/libtestengine.dylib

This can't really be done though: the .dylib extension won't work on
Linux because shared objects are .so files.

There is a way to generate and use .so files on a MAC as well,
according to the openssl people (half the mac engines seem to have a
.so extension and the other half a .dylib one), I'll see if I can
figure out what it is.

James
Ilya Shipitsin Feb. 14, 2020, 2:33 a.m. UTC | #3
пт, 14 февр. 2020 г. в 18:05, James Bottomley <
James.Bottomley@hansenpartnership.com>:

> On Thu, 2020-02-13 at 19:18 +0100, Arne Schwabe wrote:
> > Am 10.02.18 um 23:50 schrieb James Bottomley:
> > > Testing engines is problematic, so one of the prerequisites built
> > > for the tests is a simple openssl engine that reads a non-standard
> > > PEM guarded key.  The test is simply can we run a client/server
> > > configuration with the usual sample key replaced by an engine key.
> > > The trivial engine prints out some operations and we check for
> > > these in the log to make sure the engine was used to load the key
> > > and that it correctly got the password.
> >
> > This tests the openssl engine functionality in a sensible way. But I
> > think it is not fully ready to be commited. To get it working I
> > needed to do following changes on my Mac:
>
> That could be ... I only have a linux box to try this out on.
>
> > commit afa697cec15b4e54e720efe9de39c9b20b13c5c8 (HEAD ->
> > review/enginekeys)
> > Author: Arne Schwabe <arne@rfc2549.org>
> > Date:   Thu Feb 13 18:13:34 2020 +0100
> >
> >     foo
> >
> > diff --git a/tests/unit_tests/engine-key/Makefile.am
> > b/tests/unit_tests/engine-key/Makefile.am
> > index 73921965..6d7fc9c5 100644
> > --- a/tests/unit_tests/engine-key/Makefile.am
> > +++ b/tests/unit_tests/engine-key/Makefile.am
> > @@ -10,4 +10,6 @@ TESTS_ENVIRONMENT = srcdir="$(abs_srcdir)"; \
> >  TESTS = check_engine_keys.sh
> >
> >  libtestengine_la_SOURCES = libtestengine.c
> > -libtestengine_la_LDFLAGS = -rpath /lib -avoid-version
> > +libtestengine_la_LDFLAGS = @TEST_LDFLAGS@  -rpath /lib
> > +libtestengine_la_CFLAGS  = @TEST_CFLAGS@ -I$(openvpn_srcdir)
> > -I$(compat_srcdir)
> > +
> > diff --git a/tests/unit_tests/engine-key/libtestengine.c
> > b/tests/unit_tests/engine-key/libtestengine.c
> > index fa7f5de1..46ec1e33 100644
> > --- a/tests/unit_tests/engine-key/libtestengine.c
> > +++ b/tests/unit_tests/engine-key/libtestengine.c
> > @@ -30,7 +30,6 @@ static EVP_PKEY *engine_load_key(ENGINE *e, const
> > char
> > *key_id,
> >         PKCS8_PRIV_KEY_INFO *p8inf;
> >         UI *ui;
> >         char auth[256];
> > -       int len;
>
> the variable is certainly unused and can go.
>
> >         fprintf(stderr, "ENGINE: engine_load_key called\n");
> >
> > diff --git a/tests/unit_tests/engine-key/openssl.cnf
> > b/tests/unit_tests/engine-key/openssl.cnf
> > index 53200c46..e9513a92 100644
> > --- a/tests/unit_tests/engine-key/openssl.cnf
> > +++ b/tests/unit_tests/engine-key/openssl.cnf
> > @@ -9,4 +9,4 @@ engines         = engines_section
> >  testengine     = testengine_section
> >
> >  [testengine_section]
> > -dynamic_path   = $ENV::srcdir/.libs/libtestengine.so
> > +dynamic_path   = $ENV::srcdir/.libs/libtestengine.dylib
>

we use gost-engine (https://github.com/engine/gost-engine)

on both linux and osx.

for some time there was a bug in openssl:

https://github.com/openssl/openssl/issues/8950


however, for now "dylib" is used for osx. and
but we do not use "dynamic" path. we use config like that

openssl_conf = openssl_def

[openssl_def]
engines = engine_section

[engine_section]
gost = gost_section

[gost_section]
default_algorithms = ALL
engine_id = gost
CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet


>
> This can't really be done though: the .dylib extension won't work on
> Linux because shared objects are .so files.
>
> There is a way to generate and use .so files on a MAC as well,
> according to the openssl people (half the mac engines seem to have a
> .so extension and the other half a .dylib one), I'll see if I can
> figure out what it is.
>
> James
> _______________________________________________
> Openvpn-devel mailing list
> Openvpn-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/openvpn-devel
>
<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">пт, 14 февр. 2020 г. в 18:05, James Bottomley &lt;<a href="mailto:James.Bottomley@hansenpartnership.com">James.Bottomley@hansenpartnership.com</a>&gt;:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Thu, 2020-02-13 at 19:18 +0100, Arne Schwabe wrote:<br>
&gt; Am 10.02.18 um 23:50 schrieb James Bottomley:<br>
&gt; &gt; Testing engines is problematic, so one of the prerequisites built<br>
&gt; &gt; for the tests is a simple openssl engine that reads a non-standard<br>
&gt; &gt; PEM guarded key.  The test is simply can we run a client/server<br>
&gt; &gt; configuration with the usual sample key replaced by an engine key.<br>
&gt; &gt; The trivial engine prints out some operations and we check for<br>
&gt; &gt; these in the log to make sure the engine was used to load the key<br>
&gt; &gt; and that it correctly got the password.<br>
&gt; <br>
&gt; This tests the openssl engine functionality in a sensible way. But I<br>
&gt; think it is not fully ready to be commited. To get it working I<br>
&gt; needed to do following changes on my Mac:<br>
<br>
That could be ... I only have a linux box to try this out on.<br>
<br>
&gt; commit afa697cec15b4e54e720efe9de39c9b20b13c5c8 (HEAD -&gt;<br>
&gt; review/enginekeys)<br>
&gt; Author: Arne Schwabe &lt;<a href="mailto:arne@rfc2549.org" target="_blank">arne@rfc2549.org</a>&gt;<br>
&gt; Date:   Thu Feb 13 18:13:34 2020 +0100<br>
&gt; <br>
&gt;     foo<br>
&gt; <br>
&gt; diff --git a/tests/unit_tests/engine-key/Makefile.am<br>
&gt; b/tests/unit_tests/engine-key/Makefile.am<br>
&gt; index 73921965..6d7fc9c5 100644<br>
&gt; --- a/tests/unit_tests/engine-key/Makefile.am<br>
&gt; +++ b/tests/unit_tests/engine-key/Makefile.am<br>
&gt; @@ -10,4 +10,6 @@ TESTS_ENVIRONMENT = srcdir=&quot;$(abs_srcdir)&quot;; \<br>
&gt;  TESTS = check_engine_keys.sh<br>
&gt; <br>
&gt;  libtestengine_la_SOURCES = libtestengine.c<br>
&gt; -libtestengine_la_LDFLAGS = -rpath /lib -avoid-version<br>
&gt; +libtestengine_la_LDFLAGS = @TEST_LDFLAGS@  -rpath /lib<br>
&gt; +libtestengine_la_CFLAGS  = @TEST_CFLAGS@ -I$(openvpn_srcdir)<br>
&gt; -I$(compat_srcdir)<br>
&gt; +<br>
&gt; diff --git a/tests/unit_tests/engine-key/libtestengine.c<br>
&gt; b/tests/unit_tests/engine-key/libtestengine.c<br>
&gt; index fa7f5de1..46ec1e33 100644<br>
&gt; --- a/tests/unit_tests/engine-key/libtestengine.c<br>
&gt; +++ b/tests/unit_tests/engine-key/libtestengine.c<br>
&gt; @@ -30,7 +30,6 @@ static EVP_PKEY *engine_load_key(ENGINE *e, const<br>
&gt; char<br>
&gt; *key_id,<br>
&gt;         PKCS8_PRIV_KEY_INFO *p8inf;<br>
&gt;         UI *ui;<br>
&gt;         char auth[256];<br>
&gt; -       int len;<br>
<br>
the variable is certainly unused and can go.<br>
<br>
&gt;         fprintf(stderr, &quot;ENGINE: engine_load_key called\n&quot;);<br>
&gt; <br>
&gt; diff --git a/tests/unit_tests/engine-key/openssl.cnf<br>
&gt; b/tests/unit_tests/engine-key/openssl.cnf<br>
&gt; index 53200c46..e9513a92 100644<br>
&gt; --- a/tests/unit_tests/engine-key/openssl.cnf<br>
&gt; +++ b/tests/unit_tests/engine-key/openssl.cnf<br>
&gt; @@ -9,4 +9,4 @@ engines         = engines_section<br>
&gt;  testengine     = testengine_section<br>
&gt; <br>
&gt;  [testengine_section]<br>
&gt; -dynamic_path   = $ENV::srcdir/.libs/libtestengine.so<br>
&gt; +dynamic_path   = $ENV::srcdir/.libs/libtestengine.dylib<br></blockquote><div><br></div><div>we use gost-engine (<a href="https://github.com/engine/gost-engine">https://github.com/engine/gost-engine</a>)</div><div><br></div><div>on both linux and osx.</div><div><br></div><div>for some time there was a bug in openssl:<br></div><div><br></div><div><a href="https://github.com/openssl/openssl/issues/8950">https://github.com/openssl/openssl/issues/8950</a></div><div><br></div><div><br></div><div>however, for now &quot;dylib&quot; is used for osx. and <br></div><div>but we do not use &quot;dynamic&quot; path. we use config like that</div><div><br></div><div>openssl_conf = openssl_def<br><br>[openssl_def]<br>engines = engine_section<br><br>[engine_section]<br>gost = gost_section<br><br>[gost_section]<br>default_algorithms = ALL<br>engine_id = gost<br>CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
This can&#39;t really be done though: the .dylib extension won&#39;t work on<br>
Linux because shared objects are .so files.<br>
<br>
There is a way to generate and use .so files on a MAC as well,<br>
according to the openssl people (half the mac engines seem to have a<br>
.so extension and the other half a .dylib one), I&#39;ll see if I can<br>
figure out what it is.<br>
<br>
James<br>
_______________________________________________<br>
Openvpn-devel mailing list<br>
<a href="mailto:Openvpn-devel@lists.sourceforge.net" target="_blank">Openvpn-devel@lists.sourceforge.net</a><br>
<a href="https://lists.sourceforge.net/lists/listinfo/openvpn-devel" rel="noreferrer" target="_blank">https://lists.sourceforge.net/lists/listinfo/openvpn-devel</a><br>
</blockquote></div></div>
James Bottomley Feb. 15, 2020, 3:59 a.m. UTC | #4
On Fri, 2020-02-14 at 18:33 +0500, Илья Шипицин wrote:
> пт, 14 февр. 2020 г. в 18:05, James Bottomley <
> James.Bottomley@hansenpartnership.com>:
> 
> > On Thu, 2020-02-13 at 19:18 +0100, Arne Schwabe wrote:
> > > Am 10.02.18 um 23:50 schrieb James Bottomley:
> > > > Testing engines is problematic, so one of the prerequisites
> > > > built
> > > > for the tests is a simple openssl engine that reads a non-
> > > > standard
> > > > PEM guarded key.  The test is simply can we run a client/server
> > > > configuration with the usual sample key replaced by an engine
> > > > key.
> > > > The trivial engine prints out some operations and we check for
> > > > these in the log to make sure the engine was used to load the
> > > > key
> > > > and that it correctly got the password.
> > > 
> > > This tests the openssl engine functionality in a sensible way.
> > > But I
> > > think it is not fully ready to be commited. To get it working I
> > > needed to do following changes on my Mac:
> > 
> > That could be ... I only have a linux box to try this out on.
> > 
> > > commit afa697cec15b4e54e720efe9de39c9b20b13c5c8 (HEAD ->
> > > review/enginekeys)
> > > Author: Arne Schwabe <arne@rfc2549.org>
> > > Date:   Thu Feb 13 18:13:34 2020 +0100
> > > 
> > >     foo
> > > 
> > > diff --git a/tests/unit_tests/engine-key/Makefile.am
> > > b/tests/unit_tests/engine-key/Makefile.am
> > > index 73921965..6d7fc9c5 100644
> > > --- a/tests/unit_tests/engine-key/Makefile.am
> > > +++ b/tests/unit_tests/engine-key/Makefile.am
> > > @@ -10,4 +10,6 @@ TESTS_ENVIRONMENT = srcdir="$(abs_srcdir)"; \
> > >  TESTS = check_engine_keys.sh
> > > 
> > >  libtestengine_la_SOURCES = libtestengine.c
> > > -libtestengine_la_LDFLAGS = -rpath /lib -avoid-version
> > > +libtestengine_la_LDFLAGS = @TEST_LDFLAGS@  -rpath /lib
> > > +libtestengine_la_CFLAGS  = @TEST_CFLAGS@ -I$(openvpn_srcdir)
> > > -I$(compat_srcdir)
> > > +
> > > diff --git a/tests/unit_tests/engine-key/libtestengine.c
> > > b/tests/unit_tests/engine-key/libtestengine.c
> > > index fa7f5de1..46ec1e33 100644
> > > --- a/tests/unit_tests/engine-key/libtestengine.c
> > > +++ b/tests/unit_tests/engine-key/libtestengine.c
> > > @@ -30,7 +30,6 @@ static EVP_PKEY *engine_load_key(ENGINE *e,
> > > const
> > > char
> > > *key_id,
> > >         PKCS8_PRIV_KEY_INFO *p8inf;
> > >         UI *ui;
> > >         char auth[256];
> > > -       int len;
> > 
> > the variable is certainly unused and can go.
> > 
> > >         fprintf(stderr, "ENGINE: engine_load_key called\n");
> > > 
> > > diff --git a/tests/unit_tests/engine-key/openssl.cnf
> > > b/tests/unit_tests/engine-key/openssl.cnf
> > > index 53200c46..e9513a92 100644
> > > --- a/tests/unit_tests/engine-key/openssl.cnf
> > > +++ b/tests/unit_tests/engine-key/openssl.cnf
> > > @@ -9,4 +9,4 @@ engines         = engines_section
> > >  testengine     = testengine_section
> > > 
> > >  [testengine_section]
> > > -dynamic_path   = $ENV::srcdir/.libs/libtestengine.so
> > > +dynamic_path   = $ENV::srcdir/.libs/libtestengine.dylib
> 
> we use gost-engine (https://github.com/engine/gost-engine)
> 
> on both linux and osx.
> 
> for some time there was a bug in openssl:
> 
> https://github.com/openssl/openssl/issues/8950
> 
> 
> however, for now "dylib" is used for osx. and
> but we do not use "dynamic" path. we use config like that
> 
> openssl_conf = openssl_def
> 
> [openssl_def]
> engines = engine_section
> 
> [engine_section]
> gost = gost_section
> 
> [gost_section]
> default_algorithms = ALL
> engine_id = gost
> CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet

Right, that works if the engine is in the correct directory.  The
problem with this engine is that it's only built as a test
demonstration for the openvpn engine code, so it's never installed in
the openssl engines directory, so we have to tell openssl exactly where
to find it in the openvpn tree ... and that seems to involve naming the
whole file and location, including extension.

James
Ilya Shipitsin Feb. 15, 2020, 4:04 a.m. UTC | #5
сб, 15 февр. 2020 г. в 19:59, James Bottomley <
James.Bottomley@hansenpartnership.com>:

> On Fri, 2020-02-14 at 18:33 +0500, Илья Шипицин wrote:
> > пт, 14 февр. 2020 г. в 18:05, James Bottomley <
> > James.Bottomley@hansenpartnership.com>:
> >
> > > On Thu, 2020-02-13 at 19:18 +0100, Arne Schwabe wrote:
> > > > Am 10.02.18 um 23:50 schrieb James Bottomley:
> > > > > Testing engines is problematic, so one of the prerequisites
> > > > > built
> > > > > for the tests is a simple openssl engine that reads a non-
> > > > > standard
> > > > > PEM guarded key.  The test is simply can we run a client/server
> > > > > configuration with the usual sample key replaced by an engine
> > > > > key.
> > > > > The trivial engine prints out some operations and we check for
> > > > > these in the log to make sure the engine was used to load the
> > > > > key
> > > > > and that it correctly got the password.
> > > >
> > > > This tests the openssl engine functionality in a sensible way.
> > > > But I
> > > > think it is not fully ready to be commited. To get it working I
> > > > needed to do following changes on my Mac:
> > >
> > > That could be ... I only have a linux box to try this out on.
> > >
> > > > commit afa697cec15b4e54e720efe9de39c9b20b13c5c8 (HEAD ->
> > > > review/enginekeys)
> > > > Author: Arne Schwabe <arne@rfc2549.org>
> > > > Date:   Thu Feb 13 18:13:34 2020 +0100
> > > >
> > > >     foo
> > > >
> > > > diff --git a/tests/unit_tests/engine-key/Makefile.am
> > > > b/tests/unit_tests/engine-key/Makefile.am
> > > > index 73921965..6d7fc9c5 100644
> > > > --- a/tests/unit_tests/engine-key/Makefile.am
> > > > +++ b/tests/unit_tests/engine-key/Makefile.am
> > > > @@ -10,4 +10,6 @@ TESTS_ENVIRONMENT = srcdir="$(abs_srcdir)"; \
> > > >  TESTS = check_engine_keys.sh
> > > >
> > > >  libtestengine_la_SOURCES = libtestengine.c
> > > > -libtestengine_la_LDFLAGS = -rpath /lib -avoid-version
> > > > +libtestengine_la_LDFLAGS = @TEST_LDFLAGS@  -rpath /lib
> > > > +libtestengine_la_CFLAGS  = @TEST_CFLAGS@ -I$(openvpn_srcdir)
> > > > -I$(compat_srcdir)
> > > > +
> > > > diff --git a/tests/unit_tests/engine-key/libtestengine.c
> > > > b/tests/unit_tests/engine-key/libtestengine.c
> > > > index fa7f5de1..46ec1e33 100644
> > > > --- a/tests/unit_tests/engine-key/libtestengine.c
> > > > +++ b/tests/unit_tests/engine-key/libtestengine.c
> > > > @@ -30,7 +30,6 @@ static EVP_PKEY *engine_load_key(ENGINE *e,
> > > > const
> > > > char
> > > > *key_id,
> > > >         PKCS8_PRIV_KEY_INFO *p8inf;
> > > >         UI *ui;
> > > >         char auth[256];
> > > > -       int len;
> > >
> > > the variable is certainly unused and can go.
> > >
> > > >         fprintf(stderr, "ENGINE: engine_load_key called\n");
> > > >
> > > > diff --git a/tests/unit_tests/engine-key/openssl.cnf
> > > > b/tests/unit_tests/engine-key/openssl.cnf
> > > > index 53200c46..e9513a92 100644
> > > > --- a/tests/unit_tests/engine-key/openssl.cnf
> > > > +++ b/tests/unit_tests/engine-key/openssl.cnf
> > > > @@ -9,4 +9,4 @@ engines         = engines_section
> > > >  testengine     = testengine_section
> > > >
> > > >  [testengine_section]
> > > > -dynamic_path   = $ENV::srcdir/.libs/libtestengine.so
> > > > +dynamic_path   = $ENV::srcdir/.libs/libtestengine.dylib
> >
> > we use gost-engine (https://github.com/engine/gost-engine)
> >
> > on both linux and osx.
> >
> > for some time there was a bug in openssl:
> >
> > https://github.com/openssl/openssl/issues/8950
> >
> >
> > however, for now "dylib" is used for osx. and
> > but we do not use "dynamic" path. we use config like that
> >
> > openssl_conf = openssl_def
> >
> > [openssl_def]
> > engines = engine_section
> >
> > [engine_section]
> > gost = gost_section
> >
> > [gost_section]
> > default_algorithms = ALL
> > engine_id = gost
> > CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet
>
> Right, that works if the engine is in the correct directory.  The
> problem with this engine is that it's only built as a test
> demonstration for the openvpn engine code, so it's never installed in
> the openssl engines directory, so we have to tell openssl exactly where
> to find it in the openvpn tree ... and that seems to involve naming the
> whole file and location, including extension.
>
>
yes, I understand reasoning.
maybe we should add dynamic path to our tests as well.


> James
>
>
<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">сб, 15 февр. 2020 г. в 19:59, James Bottomley &lt;<a href="mailto:James.Bottomley@hansenpartnership.com">James.Bottomley@hansenpartnership.com</a>&gt;:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Fri, 2020-02-14 at 18:33 +0500, Илья Шипицин wrote:<br>
&gt; пт, 14 февр. 2020 г. в 18:05, James Bottomley &lt;<br>
&gt; <a href="mailto:James.Bottomley@hansenpartnership.com" target="_blank">James.Bottomley@hansenpartnership.com</a>&gt;:<br>
&gt; <br>
&gt; &gt; On Thu, 2020-02-13 at 19:18 +0100, Arne Schwabe wrote:<br>
&gt; &gt; &gt; Am 10.02.18 um 23:50 schrieb James Bottomley:<br>
&gt; &gt; &gt; &gt; Testing engines is problematic, so one of the prerequisites<br>
&gt; &gt; &gt; &gt; built<br>
&gt; &gt; &gt; &gt; for the tests is a simple openssl engine that reads a non-<br>
&gt; &gt; &gt; &gt; standard<br>
&gt; &gt; &gt; &gt; PEM guarded key.  The test is simply can we run a client/server<br>
&gt; &gt; &gt; &gt; configuration with the usual sample key replaced by an engine<br>
&gt; &gt; &gt; &gt; key.<br>
&gt; &gt; &gt; &gt; The trivial engine prints out some operations and we check for<br>
&gt; &gt; &gt; &gt; these in the log to make sure the engine was used to load the<br>
&gt; &gt; &gt; &gt; key<br>
&gt; &gt; &gt; &gt; and that it correctly got the password.<br>
&gt; &gt; &gt; <br>
&gt; &gt; &gt; This tests the openssl engine functionality in a sensible way.<br>
&gt; &gt; &gt; But I<br>
&gt; &gt; &gt; think it is not fully ready to be commited. To get it working I<br>
&gt; &gt; &gt; needed to do following changes on my Mac:<br>
&gt; &gt; <br>
&gt; &gt; That could be ... I only have a linux box to try this out on.<br>
&gt; &gt; <br>
&gt; &gt; &gt; commit afa697cec15b4e54e720efe9de39c9b20b13c5c8 (HEAD -&gt;<br>
&gt; &gt; &gt; review/enginekeys)<br>
&gt; &gt; &gt; Author: Arne Schwabe &lt;<a href="mailto:arne@rfc2549.org" target="_blank">arne@rfc2549.org</a>&gt;<br>
&gt; &gt; &gt; Date:   Thu Feb 13 18:13:34 2020 +0100<br>
&gt; &gt; &gt; <br>
&gt; &gt; &gt;     foo<br>
&gt; &gt; &gt; <br>
&gt; &gt; &gt; diff --git a/tests/unit_tests/engine-key/Makefile.am<br>
&gt; &gt; &gt; b/tests/unit_tests/engine-key/Makefile.am<br>
&gt; &gt; &gt; index 73921965..6d7fc9c5 100644<br>
&gt; &gt; &gt; --- a/tests/unit_tests/engine-key/Makefile.am<br>
&gt; &gt; &gt; +++ b/tests/unit_tests/engine-key/Makefile.am<br>
&gt; &gt; &gt; @@ -10,4 +10,6 @@ TESTS_ENVIRONMENT = srcdir=&quot;$(abs_srcdir)&quot;; \<br>
&gt; &gt; &gt;  TESTS = check_engine_keys.sh<br>
&gt; &gt; &gt; <br>
&gt; &gt; &gt;  libtestengine_la_SOURCES = libtestengine.c<br>
&gt; &gt; &gt; -libtestengine_la_LDFLAGS = -rpath /lib -avoid-version<br>
&gt; &gt; &gt; +libtestengine_la_LDFLAGS = @TEST_LDFLAGS@  -rpath /lib<br>
&gt; &gt; &gt; +libtestengine_la_CFLAGS  = @TEST_CFLAGS@ -I$(openvpn_srcdir)<br>
&gt; &gt; &gt; -I$(compat_srcdir)<br>
&gt; &gt; &gt; +<br>
&gt; &gt; &gt; diff --git a/tests/unit_tests/engine-key/libtestengine.c<br>
&gt; &gt; &gt; b/tests/unit_tests/engine-key/libtestengine.c<br>
&gt; &gt; &gt; index fa7f5de1..46ec1e33 100644<br>
&gt; &gt; &gt; --- a/tests/unit_tests/engine-key/libtestengine.c<br>
&gt; &gt; &gt; +++ b/tests/unit_tests/engine-key/libtestengine.c<br>
&gt; &gt; &gt; @@ -30,7 +30,6 @@ static EVP_PKEY *engine_load_key(ENGINE *e,<br>
&gt; &gt; &gt; const<br>
&gt; &gt; &gt; char<br>
&gt; &gt; &gt; *key_id,<br>
&gt; &gt; &gt;         PKCS8_PRIV_KEY_INFO *p8inf;<br>
&gt; &gt; &gt;         UI *ui;<br>
&gt; &gt; &gt;         char auth[256];<br>
&gt; &gt; &gt; -       int len;<br>
&gt; &gt; <br>
&gt; &gt; the variable is certainly unused and can go.<br>
&gt; &gt; <br>
&gt; &gt; &gt;         fprintf(stderr, &quot;ENGINE: engine_load_key called\n&quot;);<br>
&gt; &gt; &gt; <br>
&gt; &gt; &gt; diff --git a/tests/unit_tests/engine-key/openssl.cnf<br>
&gt; &gt; &gt; b/tests/unit_tests/engine-key/openssl.cnf<br>
&gt; &gt; &gt; index 53200c46..e9513a92 100644<br>
&gt; &gt; &gt; --- a/tests/unit_tests/engine-key/openssl.cnf<br>
&gt; &gt; &gt; +++ b/tests/unit_tests/engine-key/openssl.cnf<br>
&gt; &gt; &gt; @@ -9,4 +9,4 @@ engines         = engines_section<br>
&gt; &gt; &gt;  testengine     = testengine_section<br>
&gt; &gt; &gt; <br>
&gt; &gt; &gt;  [testengine_section]<br>
&gt; &gt; &gt; -dynamic_path   = $ENV::srcdir/.libs/libtestengine.so<br>
&gt; &gt; &gt; +dynamic_path   = $ENV::srcdir/.libs/libtestengine.dylib<br>
&gt; <br>
&gt; we use gost-engine (<a href="https://github.com/engine/gost-engine" rel="noreferrer" target="_blank">https://github.com/engine/gost-engine</a>)<br>
&gt; <br>
&gt; on both linux and osx.<br>
&gt; <br>
&gt; for some time there was a bug in openssl:<br>
&gt; <br>
&gt; <a href="https://github.com/openssl/openssl/issues/8950" rel="noreferrer" target="_blank">https://github.com/openssl/openssl/issues/8950</a><br>
&gt; <br>
&gt; <br>
&gt; however, for now &quot;dylib&quot; is used for osx. and<br>
&gt; but we do not use &quot;dynamic&quot; path. we use config like that<br>
&gt; <br>
&gt; openssl_conf = openssl_def<br>
&gt; <br>
&gt; [openssl_def]<br>
&gt; engines = engine_section<br>
&gt; <br>
&gt; [engine_section]<br>
&gt; gost = gost_section<br>
&gt; <br>
&gt; [gost_section]<br>
&gt; default_algorithms = ALL<br>
&gt; engine_id = gost<br>
&gt; CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet<br>
<br>
Right, that works if the engine is in the correct directory.  The<br>
problem with this engine is that it&#39;s only built as a test<br>
demonstration for the openvpn engine code, so it&#39;s never installed in<br>
the openssl engines directory, so we have to tell openssl exactly where<br>
to find it in the openvpn tree ... and that seems to involve naming the<br>
whole file and location, including extension.<br>
<br></blockquote><div><br></div><div>yes, I understand reasoning.</div><div>maybe we should add dynamic path to our tests as well.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
James<br>
<br>
</blockquote></div></div>

Patch

diff --git a/configure.ac b/configure.ac
index 2cbf3358..2f7ef8a0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1360,6 +1360,7 @@  AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = "yes"])
 AM_CONDITIONAL([ENABLE_PLUGIN_AUTH_PAM], [test "${enable_plugin_auth_pam}" = "yes"])
 AM_CONDITIONAL([ENABLE_PLUGIN_DOWN_ROOT], [test "${enable_plugin_down_root}" = "yes"])
 AM_CONDITIONAL([HAVE_LD_WRAP_SUPPORT], [test "${have_ld_wrap_support}" = "yes"])
+AM_CONDITIONAL([OPENSSL_ENGINE], [test "${have_openssl_engine}" = "yes"])
 
 sampledir="\$(docdir)/sample"
 AC_SUBST([plugindir])
@@ -1424,6 +1425,7 @@  AC_CONFIG_FILES([
         tests/unit_tests/openvpn/Makefile
         tests/unit_tests/plugins/Makefile
         tests/unit_tests/plugins/auth-pam/Makefile
+	tests/unit_tests/engine-key/Makefile
         vendor/Makefile
 	sample/Makefile
 ])
diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index 936cbb0d..558fdb46 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -92,6 +92,7 @@  setup_engine(const char *engine)
 {
     ENGINE *e = NULL;
 
+    OPENSSL_config(NULL);
     ENGINE_load_builtin_engines();
 
     if (engine)
diff --git a/tests/unit_tests/Makefile.am b/tests/unit_tests/Makefile.am
index 31d37b89..648bd7a8 100644
--- a/tests/unit_tests/Makefile.am
+++ b/tests/unit_tests/Makefile.am
@@ -1,5 +1,9 @@ 
 AUTOMAKE_OPTIONS = foreign
 
+SUBDIRS =
 if CMOCKA_INITIALIZED
-SUBDIRS = example_test openvpn plugins
+SUBDIRS += example_test openvpn plugins
+endif
+if OPENSSL_ENGINE
+SUBDIRS += engine-key
 endif
diff --git a/tests/unit_tests/engine-key/Makefile.am b/tests/unit_tests/engine-key/Makefile.am
new file mode 100644
index 00000000..f83bf817
--- /dev/null
+++ b/tests/unit_tests/engine-key/Makefile.am
@@ -0,0 +1,14 @@ 
+AUTOMAKE_OPTIONS = foreign
+
+check_LTLIBRARIES = libtestengine.la
+
+TESTS_ENVIRONMENT = srcdir="$(abs_srcdir)"; \
+	top_builddir="$(top_builddir)"; \
+	top_srcdir="$(top_srcdir)"; \
+	export srcdir top_builddir top_srcdir;
+
+TESTS = check_engine_keys.sh
+
+libtestengine_la_SOURCES = libtestengine.c
+libtestengine_la_LDFLAGS = -rpath /lib -avoid-version
+
diff --git a/tests/unit_tests/engine-key/check_engine_keys.sh b/tests/unit_tests/engine-key/check_engine_keys.sh
new file mode 100755
index 00000000..c1ae59e6
--- /dev/null
+++ b/tests/unit_tests/engine-key/check_engine_keys.sh
@@ -0,0 +1,30 @@ 
+#!/bin/sh
+
+OPENSSL_CONF="${srcdir}/openssl.cnf"
+export OPENSSL_CONF
+
+password='AT3S4PASSWD'
+
+key="${srcdir}/client.key"
+pwdfile="${srcdir}/passwd"
+
+# create an engine key for us
+sed 's/PRIVATE KEY/TEST ENGINE KEY/' < ${top_srcdir}/sample/sample-keys/client.key > ${key}
+echo "$password" > $pwdfile
+
+# note here we've induced a mismatch in the client key and the server
+# cert which openvpn should report and die.  Check that it does.  Note
+# also that this mismatch depends on openssl not openvpn, so it is
+# somewhat fragile
+${top_builddir}/src/openvpn/openvpn --cd ${top_srcdir}/sample --config sample-config-files/loopback-server --engine testengine --key ${key} --askpass $pwdfile > log.txt 2>&1
+
+# first off check we died because of a key mismatch.  If this doesn't
+# pass, suspect openssl of returning different messages and update the
+# test accordingly
+grep -q 'X509_check_private_key:key values mismatch' log.txt || { echo "Key mismatch not detected"; exit 1; }
+
+# now look for the engine prints (these are under our control)
+grep -q 'ENGINE: engine_init called' log.txt || { echo "Engine initialization not detected"; exit 1; }
+grep -q 'ENGINE: engine_load_key called' log.txt || { echo "Key was not loaded from engine"; exit 1; }
+grep -q "ENGINE: engine_load_key got password ${password}" log.txt || { echo "Key password was not retrieved by the engine"; exit 1; }
+exit 0
diff --git a/tests/unit_tests/engine-key/libtestengine.c b/tests/unit_tests/engine-key/libtestengine.c
new file mode 100644
index 00000000..4880223d
--- /dev/null
+++ b/tests/unit_tests/engine-key/libtestengine.c
@@ -0,0 +1,102 @@ 
+#include <string.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+
+static char *engine_id = "testengine";
+static char *engine_name = "Engine for testing openvpn engine key support";
+
+static int is_initialized = 0;
+
+static int engine_init(ENGINE *e)
+{
+	is_initialized = 1;
+	fprintf(stderr, "ENGINE: engine_init called\n");
+	return 1;
+}
+
+static int engine_finish(ENGINE *e)
+{
+	fprintf(stderr, "ENGINE: engine_finsh called\n");
+	is_initialized = 0;
+	return 1;
+}
+
+static EVP_PKEY *engine_load_key(ENGINE *e, const char *key_id,
+				 UI_METHOD *ui_method, void *cb_data)
+{
+	BIO *b;
+	EVP_PKEY *pkey;
+	PKCS8_PRIV_KEY_INFO *p8inf;
+	UI *ui;
+	char auth[256];
+	int len;
+
+	fprintf(stderr, "ENGINE: engine_load_key called\n");
+
+	if (!is_initialized) {
+		fprintf(stderr, "Load Key called without correct initialization\n");
+		return NULL;
+	}
+	b = BIO_new_file(key_id, "r");
+	if (!b) {
+		fprintf(stderr, "File %s does not exist or cannot be read\n", key_id); 
+		return 0;
+	}
+	/* Basically read an EVP_PKEY private key file with different
+	 * PEM guards --- we are a test engine */
+	p8inf = PEM_ASN1_read_bio((d2i_of_void *)d2i_PKCS8_PRIV_KEY_INFO,
+				 "TEST ENGINE KEY", b,
+				 NULL, NULL, NULL);
+	BIO_free(b);
+	if (!p8inf) {
+		fprintf(stderr, "Failed to read engine private key\n");
+		return NULL;
+	}
+	pkey = EVP_PKCS82PKEY(p8inf);
+
+	/* now we have a private key, pretend it had a password
+	 * this verifies the password makes it through openvpn OK */
+	ui = UI_new();
+
+	if (ui_method)
+		UI_set_method(ui, ui_method);
+
+	UI_add_user_data(ui, cb_data);
+
+	if (UI_add_input_string(ui, "enter test engine key",
+				UI_INPUT_FLAG_DEFAULT_PWD,
+				auth, 0, sizeof(auth)) == 0) {
+		fprintf(stderr, "UI_add_input_string failed\n");
+		goto out;
+	}
+
+	if (UI_process(ui)) {
+		fprintf(stderr, "UI_process failed\n");
+		goto out;
+	}
+
+	fprintf(stderr, "ENGINE: engine_load_key got password %s\n", auth);
+
+ out:
+	UI_free(ui);
+
+	return pkey;
+}
+
+
+static int engine_bind_fn(ENGINE *e, const char *id)
+{
+	if (id && strcmp(id, engine_id) != 0)
+		return 0;
+	if (!ENGINE_set_id(e, engine_id) ||
+	    !ENGINE_set_name(e, engine_name) ||
+	    !ENGINE_set_init_function(e, engine_init) ||
+	    !ENGINE_set_finish_function(e, engine_finish) ||
+	    !ENGINE_set_load_privkey_function(e, engine_load_key))
+		return 0;
+	return 1;
+}
+
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(engine_bind_fn)
diff --git a/tests/unit_tests/engine-key/openssl.cnf b/tests/unit_tests/engine-key/openssl.cnf
new file mode 100644
index 00000000..53200c46
--- /dev/null
+++ b/tests/unit_tests/engine-key/openssl.cnf
@@ -0,0 +1,12 @@ 
+HOME		= .
+openssl_conf	= openssl_init
+
+[req]
+[openssl_init]
+engines		= engines_section
+
+[engines_section]
+testengine	= testengine_section
+
+[testengine_section]
+dynamic_path	= $ENV::srcdir/.libs/libtestengine.so