[Openvpn-devel] [PATCH 2/2] Reduce --version string detail about IPv6 to just "[IPv6]".

2012-08-16 Thread Gert Doering
For 2.3 release, we do not need to have more details, as there is no
separate patch set anymore, and both IPv6 transport and IPv6 payload
(PF_INET6) have been fully integrated.

Signed-off-by: Gert Doering 
---
 src/openvpn/options.c |3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 19690e1..d25bbea 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -106,8 +106,7 @@ const char title_string[] =
 #if ENABLE_IP_PKTINFO
   " [MH]"
 #endif
-  " [PF_INET6]"
-  " [IPv6 payload 20110522-1 (2.2.0)]"
+  " [IPv6]"
   " built on " __DATE__
 ;

-- 
1.7.3.5




[Openvpn-devel] [PATCH 1/2] Put actual OpenVPN command line on top of corresponding log file.

2012-08-16 Thread Gert Doering
This is useful if a test fails, and the tester wants to run the very
same OpenVPN call with the very same arguments interactively to
pinpoint and fix the problem.

Signed-off-by: Gert Doering 
---
 tests/t_client.sh.in |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/tests/t_client.sh.in b/tests/t_client.sh.in
index 8c66033..189eecc 100755
--- a/tests/t_client.sh.in
+++ b/tests/t_client.sh.in
@@ -234,7 +234,8 @@ do
 fi

 echo " run openvpn $openvpn_conf"
-$RUN_SUDO "${top_builddir}/src/openvpn/openvpn" $openvpn_conf 
>$LOGDIR/$SUF:openvpn.log &
+echo "# src/openvpn/openvpn $openvpn_conf" >$LOGDIR/$SUF:openvpn.log
+$RUN_SUDO "${top_builddir}/src/openvpn/openvpn" $openvpn_conf 
>>$LOGDIR/$SUF:openvpn.log &
 opid=$!

 # make sure openvpn client is terminated in case shell exits
-- 
1.7.3.5




[Openvpn-devel] housekeeping patches for 2.3

2012-08-16 Thread Gert Doering
Hi,

as discussed on IRC, the "--version" output for IPv6 is no longer
useful in its existing form -> shorten (but keep, to point out "yes,
this has IPv6" even if *we* all know).

Add another convenience patch to t_client.sh, to put the command line
used by a specific test run into the corresponding openvpn log file,
so you can always see what command was run (t_client.sh prints this,
but if you clear the screen in between, it's good to have a place to
go and look it up).

gert




[Openvpn-devel] [PATCH] Keep pre-existing tun/tap devices around on *BSD

2012-08-16 Thread Gert Doering
This amends commit 62c613d46dc49 to check whether a named tun/tap
device ("--dev tunX" instead of "--dev tun") exists before OpenVPN
started - if yes, keep around at program end.  If no, destroy.

Also has a spelling fix, and changes clear_tuntap() to be "static"
(only ever called from within tun.c).

Tested on FreeBSD 7.4, FreeBSD 9.0, NetBSD 5.1, OpenBSD 4.9

Signed-off-by: Gert Doering 
Acked-by: Eric Crist 
---
 src/openvpn/tun.c |   22 +-
 src/openvpn/tun.h |4 +++-
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c
index 6218b73..ed67261 100644
--- a/src/openvpn/tun.c
+++ b/src/openvpn/tun.c
@@ -890,7 +890,7 @@ do_ifconfig (struct tuntap *tt,
 #elif defined(TARGET_OPENBSD)

   /*
-   * On OpenBSD, tun interfaces are persistant if created with
+   * On OpenBSD, tun interfaces are persistent if created with
* "ifconfig tunX create", and auto-destroyed if created by
* opening "/dev/tunX" (so we just use the /dev/tunX)
*/
@@ -1235,7 +1235,7 @@ do_ifconfig (struct tuntap *tt,
   gc_free ();
 }

-void
+static void
 clear_tuntap (struct tuntap *tuntap)
 {
   CLEAR (*tuntap);
@@ -1344,6 +1344,13 @@ open_tun_generic (const char *dev, const char *dev_type, 
const char *dev_node,

   if (!dynamic_opened)
{
+ /* has named device existed before? if so, don't destroy at end */
+ if ( if_nametoindex( dev ) > 0 )
+   {
+ msg (M_INFO, "TUN/TAP device %s exists previously, keep at 
program end", dev );
+ tt->persistent_if = true;
+   }
+
  if ((tt->fd = open (tunname, O_RDWR)) < 0)
msg (M_ERR, "Cannot open TUN/TAP dev %s", tunname);
}
@@ -2030,7 +2037,7 @@ close_tun (struct tuntap* tt)
 {
   /* only *TAP* devices need destroying, tun devices auto-self-destruct
*/
-  if (tt && tt->type == DEV_TYPE_TUN )
+  if (tt && (tt->type == DEV_TYPE_TUN || tt->persistent_if ) )
 {
   close_tun_generic (tt);
   free(tt);
@@ -2165,7 +2172,7 @@ close_tun (struct tuntap *tt)
 {
   /* only tun devices need destroying, tap devices auto-self-destruct
*/
-  if (tt && tt->type != DEV_TYPE_TUN )
+  if (tt && ( tt->type != DEV_TYPE_TUN || tt->persistent_if ) )
 {
   close_tun_generic (tt);
   free(tt);
@@ -2303,7 +2310,12 @@ open_tun (const char *dev, const char *dev_type, const 
char *dev_node, struct tu
 void
 close_tun (struct tuntap *tt)
 {
-  if (tt)
+  if (tt && tt->persistent_if )/* keep pre-existing if around 
*/
+{
+  close_tun_generic (tt);
+  free (tt);
+}
+  else if (tt) /* close and destroy */
 {
   struct gc_arena gc = gc_new ();
   struct argv argv;
diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h
index 9bd990f..8622bf8 100644
--- a/src/openvpn/tun.h
+++ b/src/openvpn/tun.h
@@ -137,6 +137,8 @@ struct tuntap

   bool ipv6;

+  bool persistent_if;  /* if existed before, keep on program end */
+
   struct tuntap_options options; /* options set on command line */

   char *actual_name; /* actual name of TUN/TAP dev, usually including unit 
number */
@@ -201,7 +203,7 @@ tuntap_defined (const struct tuntap *tt)
  * Function prototypes
  */

-void clear_tuntap (struct tuntap *tuntap);
+static void clear_tuntap (struct tuntap *tuntap);

 void open_tun (const char *dev, const char *dev_type, const char *dev_node,
   struct tuntap *tt);
-- 
1.7.3.5




Re: [Openvpn-devel] RFC: tun/tap cleanup at program end

2012-08-16 Thread Eric Crist
On Aug 15, 2012, at 05:53:40, Gert Doering  wrote:

> Hi,
> 
> On Wed, Aug 15, 2012 at 12:00:12PM +0200, Gert Doering wrote:
>>  3 - check for the existance of "--dev tap3" and remember, not cleaning
>>  if it existed previously, doing this with RT_NETLINK which should
>>  be sufficiently portable across all BSDs.  Same advantage as "2",
>>  hopefully much nicer implementation.
> 
> Here we go.  I discovered if_nametoindex(), which is really handy for
> this :-)
> 
> Eric, please test whether this solves your issues.
> 
> David, please do *not yet* commit, even if someone ACKs - I need to test
> this on OpenBSD, NetBSD and FreeBSD 9 as well.  So far, only tested on 
> FreeBSD 7.4 (and works).

I'm comfortable giving my ACK to this patch.

-
Eric F Crist







[Openvpn-devel] [PATCH 7/7] change HMAC to MAC where applicable

2012-08-16 Thread Heiko Hund
Sine there's --auth gost-mac, using HMAC throughout the code
is misleading. Especially in the crypto code itself.

This changes function and variable names as well as comments
to use the more generic MAC instead.

Signed-off-by: Heiko Hund 
---
 doc/openvpn.8  |   46 ++---
 sample/sample-config-files/server.conf |2 +-
 src/openvpn/crypto.c   |  118 
 src/openvpn/crypto.h   |   42 ++--
 src/openvpn/crypto_backend.h   |   58 
 src/openvpn/crypto_openssl.c   |   42 ++--
 src/openvpn/crypto_openssl.h   |6 +-
 src/openvpn/crypto_polarssl.c  |   22 +++---
 src/openvpn/crypto_polarssl.h  |4 +-
 src/openvpn/forward.c  |4 +-
 src/openvpn/forward.h  |2 +-
 src/openvpn/init.c |2 +-
 src/openvpn/ntlm.c |   10 +--
 src/openvpn/openvpn.h  |8 +--
 src/openvpn/options.c  |2 +-
 src/openvpn/ssl.c  |   94 -
 src/openvpn/ssl.h  |   12 ++--
 src/openvpn/ssl_common.h   |4 +-
 18 files changed, 239 insertions(+), 239 deletions(-)

diff --git a/doc/openvpn.8 b/doc/openvpn.8
index d967ebd..c10283c 100644
--- a/doc/openvpn.8
+++ b/doc/openvpn.8
@@ -3565,14 +3565,14 @@ which was generated with
 The optional
 .B direction
 parameter enables the use of 4 distinct keys
-(HMAC-send, cipher-encrypt, HMAC-receive, cipher-decrypt), so that
-each data flow direction has a different set of HMAC and cipher keys.
+(MAC-send, cipher-encrypt, MAC-receive, cipher-decrypt), so that
+each data flow direction has a different set of MAC and cipher keys.
 This has a number of desirable security properties including
 eliminating certain kinds of DoS and message replay attacks.

 When the
 .B direction
-parameter is omitted, 2 keys are used bidirectionally, one for HMAC
+parameter is omitted, 2 keys are used bidirectionally, one for MAC
 and the other for encryption/decryption.

 The
@@ -3622,25 +3622,25 @@ but random-looking data.
 .\"*
 .TP
 .B \-\-auth alg
-Authenticate packets with HMAC using message
-digest algorithm
+Authenticate packets with a message authentication algorithm (MAC) using
+message digest algorithm
 .B alg.
 (The default is
 .B SHA1
 ).
-HMAC is a commonly used message authentication algorithm (MAC) that uses
+The commonly used message authentication algorithm is HMAC that uses
 a data string, a secure hash algorithm, and a key, to produce
 a digital signature.

-OpenVPN's usage of HMAC is to first encrypt a packet, then HMAC the resulting 
ciphertext.
+OpenVPN's usage of the MAC is to first encrypt a packet, then MAC the 
resulting ciphertext.

-In static-key encryption mode, the HMAC key
+In static-key encryption mode, the MAC key
 is included in the key file generated by
 .B \-\-genkey.
-In TLS mode, the HMAC key is dynamically generated and shared
+In TLS mode, the MAC key is dynamically generated and shared
 between peers via the TLS control channel.  If OpenVPN receives a packet with
-a bad HMAC it will drop the packet.
-HMAC usually adds 16 or 20 bytes per packet.
+a bad MAC it will drop the packet.
+MACs usually adds 16 or 20 bytes per packet.
 Set
 .B alg=none
 to disable authentication.
@@ -3945,12 +3945,12 @@ TLS mode is the most powerful crypto mode of OpenVPN in 
both security and flexib
 TLS mode works by establishing control and
 data channels which are multiplexed over a single TCP/UDP port.  OpenVPN 
initiates
 a TLS session over the control channel and uses it to exchange cipher
-and HMAC keys to protect the data channel.  TLS mode uses a robust reliability
+and MAC keys to protect the data channel.  TLS mode uses a robust reliability
 layer over the UDP connection for all control channel communication, while
 the data channel, over which encrypted tunnel data passes, is forwarded without
 any mediation.  The result is the best of both worlds: a fast data channel
 that forwards over UDP with only the overhead of encrypt,
-decrypt, and HMAC functions,
+decrypt, and MAC functions,
 and a control channel that provides all of the security features of TLS,
 including certificate-based authentication and Diffie Hellman forward secrecy.

@@ -4226,7 +4226,7 @@ for protecting the tunnel data channel is generated and
 exchanged over the TLS session.

 In method 1 (the default for OpenVPN 1.x), both sides generate
-random encrypt and HMAC-send keys which are forwarded to
+random encrypt and MAC-send keys which are forwarded to
 the other host over the TLS channel.

 In method 2, (the default for OpenVPN 2.0)
@@ -4364,14 +4364,14 @@ Exit on TLS negotiation failure.
 .\"*
 .TP
 .B \-\-tls-auth file [direction]
-Add 

[Openvpn-devel] [PATCH 6/7] do MACs using EVP_MD_CTX with openssl >= 1.0.0

2012-08-16 Thread Heiko Hund
Using EVP_MD_CTX for MAC calculation allows to use other algorithms
than HMAC. In this particular case it allows the GOST-MAC to be used.
GOST-MAC uses a 256 bit key and produces a 32 bit signature.

Unfortunately OpenSSL has no API for querying a MAC's key length, so
the key length is returned statically in the case of GOST-MAC.

Signed-off-by: Heiko Hund 
---
 src/openvpn/crypto_openssl.c |   62 ++
 src/openvpn/crypto_openssl.h |4 +++
 2 files changed, 66 insertions(+)

diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index 5665e29..b5f3cef 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -714,6 +714,66 @@ md_ctx_final (EVP_MD_CTX *ctx, uint8_t *dst)
  *
  */

+#if SSLEAY_VERSION_NUMBER >= 0x1000L
+
+int
+hmac_key_size (const EVP_MD *kt)
+{
+  if (NULL == kt)
+return 0;
+  return (EVP_MD_type (kt) == NID_id_Gost28147_89_MAC ? 32 : md_kt_size (kt));
+}
+
+void
+hmac_ctx_init (EVP_MD_CTX *ctx, const uint8_t *key, int key_len,
+const EVP_MD *kt)
+{
+  int pkey_id;
+
+  ASSERT (NULL != kt && NULL != ctx);
+
+  pkey_id = ( EVP_MD_type (kt) == NID_id_Gost28147_89_MAC
+  ? NID_id_Gost28147_89_MAC : EVP_PKEY_HMAC );
+
+  EVP_MD_CTX_init (ctx);
+  EVP_DigestSignInit (ctx, NULL, kt, NULL,
+  EVP_PKEY_new_mac_key (pkey_id, NULL, (uint8_t *)key, key_len));
+}
+
+void
+hmac_ctx_cleanup (EVP_MD_CTX *ctx)
+{
+  /* frees the key implicitly */
+  EVP_MD_CTX_cleanup (ctx);
+}
+
+int
+hmac_ctx_size (const EVP_MD_CTX *ctx)
+{
+  return EVP_MD_CTX_size (ctx);
+}
+
+void
+hmac_ctx_reset (EVP_MD_CTX *ctx)
+{
+  EVP_DigestInit_ex (ctx, EVP_MD_CTX_md (ctx), NULL);
+}
+
+void
+hmac_ctx_update (EVP_MD_CTX *ctx, const uint8_t *src, int src_len)
+{
+  EVP_DigestSignUpdate (ctx, src, src_len);
+}
+
+void
+hmac_ctx_final (EVP_MD_CTX *ctx, uint8_t *dst)
+{
+  size_t mac_len = hmac_ctx_size (ctx);
+  EVP_DigestSignFinal (ctx, dst, _len);
+}
+
+#else /* SSLEAY_VERSION_NUMBER >= 0x1000L */
+
 int
 hmac_key_size (const EVP_MD *kt)
 {
@@ -769,4 +829,6 @@ hmac_ctx_final (HMAC_CTX *ctx, uint8_t *dst)
   HMAC_Final (ctx, dst, _hmac_len);
 }

+#endif /* SSLEAY_VERSION_NUMBER >= 0x1000L */
+
 #endif /* ENABLE_CRYPTO && ENABLE_CRYPTO_OPENSSL */
diff --git a/src/openvpn/crypto_openssl.h b/src/openvpn/crypto_openssl.h
index f883c2a..d7c9dd8 100644
--- a/src/openvpn/crypto_openssl.h
+++ b/src/openvpn/crypto_openssl.h
@@ -47,7 +47,11 @@ typedef EVP_CIPHER_CTX cipher_ctx_t;
 typedef EVP_MD_CTX md_ctx_t;

 /** Generic HMAC %context. */
+#if OPENSSL_VERSION_NUMBER >= 0x1000L
+typedef EVP_MD_CTX hmac_ctx_t;
+#else
 typedef HMAC_CTX hmac_ctx_t;
+#endif

 /** Maximum length of an IV */
 #define OPENVPN_MAX_IV_LENGTH  EVP_MAX_IV_LENGTH
-- 
1.7.9.5




[Openvpn-devel] [PATCH 4/7] support crypto engine options

2012-08-16 Thread Heiko Hund
OpenVPN supports using OpenSSL engines by loading them with the
--engine configuration option. Some of those engines require
configuration options themself.

This patch extends the --engine option so that engine-options can be
specified as well.

Signed-off-by: Heiko Hund 
---
 doc/openvpn.8 |   11 ++-
 src/openvpn/crypto.c  |4 ++--
 src/openvpn/crypto.h  |2 +-
 src/openvpn/crypto_backend.h  |   17 -
 src/openvpn/crypto_openssl.c  |   33 +
 src/openvpn/crypto_polarssl.c |4 ++--
 src/openvpn/options.c |   32 +++-
 src/openvpn/options.h |3 ++-
 src/openvpn/ssl.c |4 ++--
 src/openvpn/ssl.h |2 +-
 10 files changed, 80 insertions(+), 32 deletions(-)

diff --git a/doc/openvpn.8 b/doc/openvpn.8
index 56be29e..d967ebd 100644
--- a/doc/openvpn.8
+++ b/doc/openvpn.8
@@ -3704,13 +3704,14 @@ to disable the PRNG and use the OpenSSL RAND_bytes 
function
 instead for all of OpenVPN's pseudo-random number needs.
 .\"*
 .TP
-.B \-\-engine [engine-name]
-Enable OpenSSL hardware-based crypto engine functionality.
-
+.B \-\-engine [engine-name [engine-option ...]]
+Enable OpenSSL crypto engine functionality.
 If
 .B engine-name
-is specified,
-use a specific crypto engine.  Use the
+is specified, use a specific crypto engine.
+.B engine-options
+must be given as name=value pairs.
+Use the
 .B \-\-show-engines
 standalone option to list the crypto engines which are
 supported by OpenSSL.
diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
index b95865e..7fdbb95 100644
--- a/src/openvpn/crypto.c
+++ b/src/openvpn/crypto.c
@@ -1376,9 +1376,9 @@ get_random()
 #ifndef ENABLE_SSL

 void
-init_ssl_lib (const char *engine_name)
+init_ssl_lib (const struct crypto_engine *engine)
 {
-  crypto_init_lib (engine_name);
+  crypto_init_lib (engine);
 }

 void
diff --git a/src/openvpn/crypto.h b/src/openvpn/crypto.h
index cd08cf3..5c34597 100644
--- a/src/openvpn/crypto.h
+++ b/src/openvpn/crypto.h
@@ -358,7 +358,7 @@ void get_tls_handshake_key (const struct key_type *key_type,

 #else

-void init_ssl_lib (const char *engine_name);
+void init_ssl_lib (const struct crypto_engine *engine);
 void free_ssl_lib (void);

 #endif /* ENABLE_SSL */
diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h
index 9727a92..4b68687 100644
--- a/src/openvpn/crypto_backend.h
+++ b/src/openvpn/crypto_backend.h
@@ -40,10 +40,25 @@


 /*
+ * Structures for crypto library engine configuration.
+ */
+struct crypto_engine_option
+{
+  struct crypto_engine_option *next;
+  const char *name;
+  const char *value;
+};
+struct crypto_engine
+{
+  const char *name;
+  struct crypto_engine_option *options;
+};
+
+/*
  * This routine should have additional OpenSSL crypto library initialisations
  * used by both crypto and ssl components of OpenVPN.
  */
-void crypto_init_lib (const char *engine_name);
+void crypto_init_lib (const struct crypto_engine *engine);

 void crypto_uninit_lib (void);

diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index a7ee168..deaf0ca 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -135,7 +135,7 @@ try_load_engine (const char *engine)
 }

 static ENGINE *
-setup_engine (const char *engine)
+setup_engine (const struct crypto_engine *engine)
 {
   ENGINE *e = NULL;

@@ -143,24 +143,33 @@ setup_engine (const char *engine)

   if (engine)
 {
-  if (strcmp (engine, "auto") == 0)
+  struct crypto_engine_option *o;
+  
+  if (strcmp (engine->name, "auto") == 0)
{
  msg (M_INFO, "Initializing OpenSSL auto engine support");
  ENGINE_register_all_complete ();
  return NULL;
}
-  if ((e = ENGINE_by_id (engine)) == NULL
-&& (e = try_load_engine (engine)) == NULL)
+  if ((e = ENGINE_by_id (engine->name)) == NULL
+&& (e = try_load_engine (engine->name)) == NULL)
{
- msg (M_FATAL, "OpenSSL error: cannot load engine '%s'", engine);
+ msg (M_FATAL, "OpenSSL error: cannot load engine '%s'", engine->name);
}

   if (!ENGINE_set_default (e, ENGINE_METHOD_ALL))
{
  msg (M_FATAL, "OpenSSL error: ENGINE_set_default failed on engine 
'%s'",
-  engine);
+  engine->name);
}

+  for (o = engine->options; o; o = o->next)
+{
+  if (!ENGINE_ctrl_cmd_string (e, o->name, o->value, 0))
+msg (M_FATAL, "OpenSSL error: ENGINE_ctrl_cmd_string failed on 
engine '%s'",
+engine->name);
+}
+
   msg (M_INFO, "Initializing OpenSSL support for engine '%s'",
   ENGINE_get_id (e));
 }
@@ -170,14 +179,14 @@ setup_engine (const char *engine)
 #endif /* HAVE_OPENSSL_ENGINE */

 static void
-crypto_init_lib_engine (const 

[Openvpn-devel] [PATCH 3/7] remove API for crypto engine initialization

2012-08-16 Thread Heiko Hund
Since the crypto library and the crypto engine initialization are now
happening at the same time, there's no apparent need for two distinct
APIs the init them anymore.

The crypto engine is now initialized within the crypto library init
function, which makes to code look a bit cleaner.

Signed-off-by: Heiko Hund 
---
 src/openvpn/crypto.c  |4 ++--
 src/openvpn/crypto.h  |2 +-
 src/openvpn/crypto_backend.h  |7 +--
 src/openvpn/crypto_openssl.c  |7 +--
 src/openvpn/crypto_polarssl.c |   18 --
 src/openvpn/openvpn.c |4 +---
 src/openvpn/ssl.c |5 ++---
 src/openvpn/ssl.h |2 +-
 8 files changed, 17 insertions(+), 32 deletions(-)

diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
index 2f67e5e..b95865e 100644
--- a/src/openvpn/crypto.c
+++ b/src/openvpn/crypto.c
@@ -1376,9 +1376,9 @@ get_random()
 #ifndef ENABLE_SSL

 void
-init_ssl_lib (void)
+init_ssl_lib (const char *engine_name)
 {
-  crypto_init_lib ();
+  crypto_init_lib (engine_name);
 }

 void
diff --git a/src/openvpn/crypto.h b/src/openvpn/crypto.h
index 3b4b88e..cd08cf3 100644
--- a/src/openvpn/crypto.h
+++ b/src/openvpn/crypto.h
@@ -358,7 +358,7 @@ void get_tls_handshake_key (const struct key_type *key_type,

 #else

-void init_ssl_lib (void);
+void init_ssl_lib (const char *engine_name);
 void free_ssl_lib (void);

 #endif /* ENABLE_SSL */
diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h
index 1eac611..9727a92 100644
--- a/src/openvpn/crypto_backend.h
+++ b/src/openvpn/crypto_backend.h
@@ -43,17 +43,12 @@
  * This routine should have additional OpenSSL crypto library initialisations
  * used by both crypto and ssl components of OpenVPN.
  */
-void crypto_init_lib (void);
+void crypto_init_lib (const char *engine_name);

 void crypto_uninit_lib (void);

 void crypto_clear_error (void);

-/*
- * Initialise the given named crypto engine.
- */
-void crypto_init_lib_engine (const char *engine_name);
-
 #ifdef DMALLOC
 /*
  * OpenSSL memory debugging.  If dmalloc debugging is enabled, tell
diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index 5342502..a7ee168 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -169,7 +169,7 @@ setup_engine (const char *engine)

 #endif /* HAVE_OPENSSL_ENGINE */

-void
+static void
 crypto_init_lib_engine (const char *engine_name)
 {
 #if HAVE_OPENSSL_ENGINE
@@ -192,8 +192,11 @@ crypto_init_lib_engine (const char *engine_name)
  */

 void
-crypto_init_lib (void)
+crypto_init_lib (const char *engine_name)
 {
+  if (engine_name)
+crypto_init_lib_engine (engine_name);
+
 #ifndef USE_SSL
 #ifndef ENABLE_SMALL
   ERR_load_crypto_strings ();
diff --git a/src/openvpn/crypto_polarssl.c b/src/openvpn/crypto_polarssl.c
index 3978a3c..b7f13e3 100644
--- a/src/openvpn/crypto_polarssl.c
+++ b/src/openvpn/crypto_polarssl.c
@@ -54,26 +54,16 @@

 /*
  *
- * Hardware engine support. Allows loading/unloading of engines.
- *
- */
-
-void
-crypto_init_lib_engine (const char *engine_name)
-{
-  msg (M_WARN, "Note: PolarSSL hardware crypto engine functionality is not "
-  "available");
-}
-
-/*
- *
  * Functions related to the core crypto library
  *
  */

 void
-crypto_init_lib (void)
+crypto_init_lib (const char *engine_name)
 {
+  if (engine_name)
+msg (M_WARN, "Note: PolarSSL hardware crypto engine functionality is not "
+"available");
 }

 void
diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c
index 170abe1..65f43c3 100644
--- a/src/openvpn/openvpn.c
+++ b/src/openvpn/openvpn.c
@@ -192,9 +192,7 @@ openvpn_main (int argc, char *argv[])
   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_ssl_lib (c.options.engine);

   /*
* init PRNG used for IV generation
diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index 19512c0..e9a7d0a 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -153,11 +153,10 @@ tls_init_control_channel_frame_parameters(const struct 
frame *data_channel_frame
 }

 void
-init_ssl_lib ()
+init_ssl_lib (const char *engine_name)
 {
+  crypto_init_lib (engine_name);
   tls_init_lib ();
-
-  crypto_init_lib ();
 }

 void
diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h
index cd7cae2..daa654c 100644
--- a/src/openvpn/ssl.h
+++ b/src/openvpn/ssl.h
@@ -144,7 +144,7 @@ struct tls_auth_standalone
 /*
  * Prepare the SSL library for use
  */
-void init_ssl_lib (void);
+void init_ssl_lib (const char *engine_name);

 /*
  * Free any internal state that the SSL library might have
-- 
1.7.9.5




[Openvpn-devel] [PATCH 2/7] init crypto engine before SSL library

2012-08-16 Thread Heiko Hund
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 
---
 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_free ();
-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_free ();
+  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 (, 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 (, 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 ();
  gc_reset ();
}
-- 
1.7.9.5




[Openvpn-devel] [PATCH 1/7] refine assertion to allow other modes than CBC

2012-08-16 Thread Heiko Hund
cipher_ctx_final() only returns an outlen in CBC mode. If CFB or OFB
are used the assertion outlen == iv_len is always false.

There's no CBC mode defined for the GOST 28147-89 block cipher. Hence
this patch is needed for it to work. It's needed for other ciphers like
BF-CFB as well, though.

Signed-off-by: Heiko Hund 
---
 src/openvpn/crypto.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
index ac2eecd..2f67e5e 100644
--- a/src/openvpn/crypto.c
+++ b/src/openvpn/crypto.c
@@ -153,7 +153,7 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
  /* Flush the encryption buffer */
  ASSERT(cipher_ctx_final(ctx->cipher, BPTR () + outlen, ));
  work.len += outlen;
- ASSERT (outlen == iv_size);
+ ASSERT (mode != OPENVPN_MODE_CBC || outlen == iv_size);

  /* prepend the IV to the ciphertext */
  if (opt->flags & CO_USE_IV)
-- 
1.7.9.5