Since GOST in OpenSSL is implemented in an engine, the engine must
be loaded before the SSL library is initialized for the algorithms
to become available for SSL/TLS.

This delays the initialization of the ssl lib until after the options
are parsed, so a possibly configured engine can be loaded before.

Signed-off-by: Heiko Hund <heiko.h...@sophos.com>
---
 src/openvpn/init.c    |   65 +++++++++++++++++--------------------------------
 src/openvpn/init.h    |    1 +
 src/openvpn/openvpn.c |   22 +++++++++++++++++
 3 files changed, 45 insertions(+), 43 deletions(-)

diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 270ee6a..564621d 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -589,10 +589,6 @@ init_static (void)
 {
   /* configure_path (); */

-#if defined(ENABLE_CRYPTO) && defined(DMALLOC)
-  crypto_init_dmalloc();
-#endif
-
   init_random_seed ();         /* init random() function, only used as
                                   source for weak random numbers */
   error_reset ();              /* initialize error.c */
@@ -612,15 +608,6 @@ init_static (void)

   update_time ();

-#ifdef ENABLE_CRYPTO
-  init_ssl_lib ();
-
-  /* init PRNG used for IV generation */
-  /* When forking, copy this to more places in the code to avoid fork
-     random-state predictability */
-  prng_init (NULL, 0);
-#endif
-
 #ifdef PID_TEST
   packet_id_interactive_test ();       /* test the sequence number code */
   return false;
@@ -699,29 +686,6 @@ init_static (void)
   }
 #endif

-#ifdef PRNG_TEST
-  {
-    struct gc_arena gc = gc_new ();
-    uint8_t rndbuf[8];
-    int i;
-    prng_init ("sha1", 16);
-    /*prng_init (NULL, 0);*/
-    const int factor = 1;
-    for (i = 0; i < factor * 8; ++i)
-      {
-#if 1
-       prng_bytes (rndbuf, sizeof (rndbuf));
-#else
-       ASSERT(rand_bytes (rndbuf, sizeof (rndbuf)));
-#endif
-       printf ("[%d] %s\n", i, format_hex (rndbuf, sizeof (rndbuf), 0, &gc));
-      }
-    gc_free (&gc);
-    prng_uninit ();
-    return false;
-  }
-#endif
-
 #ifdef BUFFER_LIST_AGGREGATE_TEST
   /* test buffer_list_aggregate function */
   {
@@ -798,10 +762,6 @@ init_static (void)
 void
 uninit_static (void)
 {
-#ifdef ENABLE_CRYPTO
-  free_ssl_lib ();
-#endif
-
 #ifdef ENABLE_PKCS11
   pkcs11_terminate ();
 #endif
@@ -1942,9 +1902,6 @@ key_schedule_free (struct key_schedule *ks, bool 
free_ssl_ctx)
 static void
 init_crypto_pre (struct context *c, const unsigned int flags)
 {
-  if (c->options.engine)
-    crypto_init_lib_engine (c->options.engine);
-
   if (flags & CF_LOAD_PERSISTED_PACKET_ID)
     {
       /* load a persisted packet-id for cross-session replay-protection */
@@ -3715,6 +3672,28 @@ test_crypto_thread (void *arg)
 #endif

 bool
+do_test_prng ()
+{
+#ifdef PRNG_TEST
+  struct gc_arena gc = gc_new ();
+  uint8_t rndbuf[8];
+  int i;
+  prng_init ("sha1", 16);
+  const int factor = 1;
+  for (i = 0; i < factor * 8; ++i)
+    {
+      prng_bytes (rndbuf, sizeof (rndbuf));
+      printf ("[%d] %s\n", i, format_hex (rndbuf, sizeof (rndbuf), 0, &gc));
+    }
+  gc_free (&gc);
+  prng_uninit ();
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool
 do_test_crypto (const struct options *o)
 {
 #ifdef ENABLE_CRYPTO
diff --git a/src/openvpn/init.h b/src/openvpn/init.h
index 5a1d1dc..ed95f85 100644
--- a/src/openvpn/init.h
+++ b/src/openvpn/init.h
@@ -70,6 +70,7 @@ void do_route (const struct options *options,

 void close_instance (struct context *c);

+bool do_test_prng ();
 bool do_test_crypto (const struct options *o);

 void context_gc_free (struct context *c);
diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c
index 104c9e9..170abe1 100644
--- a/src/openvpn/openvpn.c
+++ b/src/openvpn/openvpn.c
@@ -187,6 +187,25 @@ openvpn_main (int argc, char *argv[])
          /* parse command line options, and read configuration file */
          parse_argv (&c.options, argc, argv, M_USAGE, OPT_P_DEFAULT, NULL, 
c.es);

+#ifdef ENABLE_CRYPTO
+#ifdef DMALLOC
+          crypto_init_dmalloc ();
+#endif
+          /* initialize crypto and ssl/tls libraries */
+          if (c.options.engine)
+            crypto_init_lib_engine (c.options.engine);
+          init_ssl_lib ();
+
+          /*
+           * init PRNG used for IV generation
+           * when forking, copy this to more places in the code to avoid fork
+           * random-state predictability
+           */
+          prng_init (NULL, 0);
+          if (do_test_prng ())
+            break;
+#endif
+
 #ifdef ENABLE_PLUGIN
          /* plugins may contribute options configuration */
          init_verb_mute (&c, IVM_LEVEL_1);
@@ -269,6 +288,9 @@ openvpn_main (int argc, char *argv[])
            }
          while (c.sig->signal_received == SIGUSR1);

+#ifdef ENABLE_CRYPTO
+          free_ssl_lib ();
+#endif
          uninit_options (&c.options);
          gc_reset (&c.gc);
        }
-- 
1.7.9.5


Reply via email to