Re: [Openvpn-devel] [PATCH 4/4] When tls-version-min is unspecified, revert to original versioning approach.

2014-04-30 Thread James Yonan

On 28/04/2014 15:19, Steffan Karger wrote:

Hi,

On 27-04-14 22:10, Steffan Karger wrote:

On 27-04-14 19:53, Gert Doering wrote:

On Mon, Apr 21, 2014 at 01:10:04AM -0600, James Yonan wrote: The
attached patch is what I intend to commit to release/2.3 *only*,
not to master - as agreed at the IRC meeting.  "Please ACK" :-)


Sorry, but NAK.


On a more constructive note: attached a new proposal for this patch.


The OpenSSL bits look fine


On a closer look, the wrapping "if (tls_version_min > TLS_VER_UNSPEC)"
in tls_ctx_set_options() seems redundant, because TLS_VER_UNSPEC <
TLS_VER_1_0 < TLS_VER_1_1 < TLS_VER_1_2 and the ifs are checking for
"tls_version_min > TLS_VER_1_x". I've removed these changes in the
attached patch proposal.


the PolarSSL bits
would also allow for SSL_MINOR_VERSION_0, which is SSLv3 and thus a
reduction in security (and actually increases the handshake complexity).


To elaborate a bit: The naming is a bit confusing, but
SSL_MAJOR_VERSION_3 + SSL_MINOR_VERSION_O means SSLv3, ... +
SSL_MINOR_VERSION_1 means TLSv1.0, ... + SSL_MINOR_VERSION_2 means
TLSv1.1, etc. If none are given (what would happen in the previous
version of the patch), PolarSSL defaults the minimum version to SSLv3
and maximum to TLSv1.2. The attached patch thus removes the wrapping "if
(tls_version_min > TLS_VER_UNSPEC)" and sets the default to TLSv1.0 to
TLSv1.2 again. That is equal to the behaviour prior to the TLS
versioning patch.

-Steffan


This is fine.  I can ACK this.

Thanks,
James




Re: [Openvpn-devel] [PATCH 4/4] When tls-version-min is unspecified, revert to original versioning approach.

2014-04-28 Thread Steffan Karger
Hi,

On 27-04-14 22:10, Steffan Karger wrote:
> On 27-04-14 19:53, Gert Doering wrote:
>> On Mon, Apr 21, 2014 at 01:10:04AM -0600, James Yonan wrote: The
>> attached patch is what I intend to commit to release/2.3 *only*,
>> not to master - as agreed at the IRC meeting.  "Please ACK" :-)
> 
> Sorry, but NAK.

On a more constructive note: attached a new proposal for this patch.

> The OpenSSL bits look fine

On a closer look, the wrapping "if (tls_version_min > TLS_VER_UNSPEC)"
in tls_ctx_set_options() seems redundant, because TLS_VER_UNSPEC <
TLS_VER_1_0 < TLS_VER_1_1 < TLS_VER_1_2 and the ifs are checking for
"tls_version_min > TLS_VER_1_x". I've removed these changes in the
attached patch proposal.

> the PolarSSL bits
> would also allow for SSL_MINOR_VERSION_0, which is SSLv3 and thus a
> reduction in security (and actually increases the handshake complexity).

To elaborate a bit: The naming is a bit confusing, but
SSL_MAJOR_VERSION_3 + SSL_MINOR_VERSION_O means SSLv3, ... +
SSL_MINOR_VERSION_1 means TLSv1.0, ... + SSL_MINOR_VERSION_2 means
TLSv1.1, etc. If none are given (what would happen in the previous
version of the patch), PolarSSL defaults the minimum version to SSLv3
and maximum to TLSv1.2. The attached patch thus removes the wrapping "if
(tls_version_min > TLS_VER_UNSPEC)" and sets the default to TLSv1.0 to
TLSv1.2 again. That is equal to the behaviour prior to the TLS
versioning patch.

-Steffan
>From 558fdb6142f4d5b0c039437a001b13110a910e5b Mon Sep 17 00:00:00 2001
From: James Yonan 
List-Post: openvpn-devel@lists.sourceforge.net
Date: Mon, 28 Apr 2014 22:52:11 +0200
Subject: [PATCH] When tls-version-min is unspecified, revert to original
 versioning approach.

For OpenSSL, this means to use TLSv1_(client|server)_method rather
than SSLv23_(client|server)_method combined with SSL_OP_NO_x flags
for specific TLS versions to disable.

For PolarSSL, this means to implicitly control the TLS version via allowed
ciphersuites.

Point out off-by-default-now setting in the openvpn(8) man page.

This patch is only included in the release/2.3 branch, because it's a
stopgap measure.  2.4 will have it on-by-default, when the remaining
handshake problems are fully debugged and solved.

Signed-off-by: James Yonan 
Signed-off-by: Gert Doering 
Signed-off-by: Steffan Karger 
---
 doc/openvpn.8  |  8 +++-
 src/openvpn/ssl.c  |  4 ++--
 src/openvpn/ssl_backend.h  | 15 +--
 src/openvpn/ssl_openssl.c  | 18 ++
 src/openvpn/ssl_polarssl.c |  4 ++--
 5 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/doc/openvpn.8 b/doc/openvpn.8
index 585751b..c9c82ac 100644
--- a/doc/openvpn.8
+++ b/doc/openvpn.8
@@ -4275,12 +4275,18 @@ above).
 .\"*
 .TP
 .B \-\-tls-version-min version ['or-highest']
-Sets the minimum
+Enable TLS version negotiation, and set the minimum
 TLS version we will accept from the peer (default is "1.0").
 Examples for version
 include "1.0", "1.1", or "1.2".  If 'or-highest' is specified
 and version is not recognized, we will only accept the highest TLS
 version supported by the local SSL implementation.
+
+If this options is not set, the code in OpenVPN 2.3.4 will default
+to using TLS 1.0 only, without any version negotiation.  This reverts
+the beaviour to what OpenVPN versions up to 2.3.2 did, as it turned 
+out that TLS version negotiation can lead to handshake problems due
+to new signature algorithms in TLS 1.2.
 .\"*
 .TP
 .B \-\-pkcs12 file
diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index 93d81e2..ac6818e 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -486,12 +486,12 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)

   if (options->tls_server)
 {
-  tls_ctx_server_new(new_ctx);
+  tls_ctx_server_new(new_ctx, options->ssl_flags);
   tls_ctx_load_dh_params(new_ctx, options->dh_file, options->dh_file_inline);
 }
   else/* if client */
 {
-  tls_ctx_client_new(new_ctx);
+  tls_ctx_client_new(new_ctx, options->ssl_flags);
 }

   tls_ctx_set_options(new_ctx, options->ssl_flags);
diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h
index 9777242..b37b1e5 100644
--- a/src/openvpn/ssl_backend.h
+++ b/src/openvpn/ssl_backend.h
@@ -109,10 +109,11 @@ void tls_clear_error();
  * @return 		One of the TLS_VER_x constants or TLS_VER_BAD
  *  if a parse error should be flagged.
  */
-#define TLS_VER_BAD   -1
-#define TLS_VER_1_00 /* default */
-#define TLS_VER_1_11
-#define TLS_VER_1_22
+#define TLS_VER_BAD-1
+#define TLS_VER_UNSPEC  0 /* default */
+#define TLS_VER_1_0 1
+#define TLS_VER_1_1 2
+#define TLS_VER_1_2 3
 int tls_version_min_parse(const char *vstr, const char *extra);

 /**
@@ -127,15 +128,17 @@ int 

Re: [Openvpn-devel] [PATCH 4/4] When tls-version-min is unspecified, revert to original versioning approach.

2014-04-27 Thread Steffan Karger
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA256

Hi,

On 27-04-14 19:53, Gert Doering wrote:
> On Mon, Apr 21, 2014 at 01:10:04AM -0600, James Yonan wrote: The
> attached patch is what I intend to commit to release/2.3 *only*,
> not to master - as agreed at the IRC meeting.  "Please ACK" :-)

Sorry, but NAK. The OpenSSL bits look fine, but the PolarSSL bits
would also allow for SSL_MINOR_VERSION_0, which is SSLv3 and thus a
reduction in security (and actually increases the handshake complexity).

I think the ssl_polarssl.c can stay the way it is, one has to specify
tls cipher suites anyway to restrict the handshake. Or am I missing
something here?

- -Steffan
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.14 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQEcBAEBCAAGBQJTXWQgAAoJEJgCyj0AftKILQoH+wa0ojSrip0vhrPKq/AOa6Bw
cpVaDzTo6v7KiOoPf+xWfaEw9aNybd5a8GCVZlCGgSB+vOn53bLtJ7hSPL5fVzb1
8UQw5hWhWyjiZRksyCJNyYEHgzE7ZiRK/LhSd/RhYHlwUTPJfJQ6nYHlM/oMMthz
mvj0juA6jCYGCznUD/2fioy5JtpGUqpwkJzQ2hIMtqV8sxyHgJ90R6DpV6cP2nRd
AAQndNYVRhC5dQfaQtX+4TStMQK65Q7ZlHZDYb3h6TpKk93y/nWdm5tsew1oLbZ+
E27hMtswug0CSWqnSFtT+bW1shYJgrveDnHu7K1Tgh9KJ9DD2SbvXlgADCaao1U=
=uc7+
-END PGP SIGNATURE-



Re: [Openvpn-devel] [PATCH 4/4] When tls-version-min is unspecified, revert to original versioning approach.

2014-04-27 Thread Gert Doering
Hi,

On Mon, Apr 21, 2014 at 01:10:04AM -0600, James Yonan wrote:
> For OpenSSL, this means to use TLSv1_(client|server)_method rather
> than SSLv23_(client|server)_method combined with SSL_OP_NO_x flags
> for specific TLS versions to disable.
> 
> For PolarSSL, this means to avoid calling ssl_set_min_version and
> instead implicitly control the TLS version via allowed ciphersuites.

As per the discussion on IRC, I've adapted the patch to 2.3 only (some
small incompatibilities in ssl_polarssl.c), and added a section in the
openvpn.8 man page.

I have tested OpenSSL and PolarSSL builds, talking to a git master server.

With OpenSSL:

  no --tls-version-min in config --> TLSv1 is used
  --tls-version-min 1.0 or 1.2   --> TLSv1.2 is used

(clearly visible in both server and client logs)

With PolarSSL, I always get TLSv1.2, and can't really see whether or not
it makes a difference.  But given James' comments, this seems to be 
expected (I didn't play with --tls-cipher settings).

The attached patch is what I intend to commit to release/2.3 *only*, not
to master - as agreed at the IRC meeting.  "Please ACK" :-)

gert
-- 
USENET is *not* the non-clickable part of WWW!
   //www.muc.de/~gert/
Gert Doering - Munich, Germany g...@greenie.muc.de
fax: +49-89-35655025g...@net.informatik.tu-muenchen.de
From 986a3382de536a3ca530429f985f9989783d5996 Mon Sep 17 00:00:00 2001
From: James Yonan 
List-Post: openvpn-devel@lists.sourceforge.net
Date: Mon, 21 Apr 2014 01:10:04 -0600
Subject: [PATCH] When tls-version-min is unspecified, revert to original
 versioning approach.

For OpenSSL, this means to use TLSv1_(client|server)_method rather
than SSLv23_(client|server)_method combined with SSL_OP_NO_x flags
for specific TLS versions to disable.

For PolarSSL, this means to avoid calling ssl_set_min_version and
instead implicitly control the TLS version via allowed ciphersuites.

Point out off-by-default-now setting in the openvpn(8) man page.

This patch is only included in the release/2.3 branch, because it's a
stopgap measure.  2.4 will have it on-by-default, when the remaining
handshake problems are fully debugged and solved.

Signed-off-by: James Yonan 
Signed-off-by: Gert Doering 
---
 doc/openvpn.8  |  8 +++-
 src/openvpn/ssl.c  |  4 ++--
 src/openvpn/ssl_backend.h  | 15 +--
 src/openvpn/ssl_openssl.c  | 33 +++--
 src/openvpn/ssl_polarssl.c | 41 ++---
 5 files changed, 63 insertions(+), 38 deletions(-)

diff --git a/doc/openvpn.8 b/doc/openvpn.8
index 7a33f8a..10ec1f5 100644
--- a/doc/openvpn.8
+++ b/doc/openvpn.8
@@ -4275,12 +4275,18 @@ above).
 .\"*
 .TP
 .B \-\-tls-version-min version ['or-highest']
-Sets the minimum
+Enable TLS version negotiation, and set the minimum
 TLS version we will accept from the peer (default is "1.0").
 Examples for version
 include "1.0", "1.1", or "1.2".  If 'or-highest' is specified
 and version is not recognized, we will only accept the highest TLS
 version supported by the local SSL implementation.
+
+If this options is not set, the code in OpenVPN 2.3.4 will default
+to using TLS 1.0 only, without any version negotiation.  This reverts
+the beaviour to what OpenVPN versions up to 2.3.2 did, as it turned 
+out that TLS version negotiation can lead to handshake problems due
+to new signature algorithms in TLS 1.2.
 .\"*
 .TP
 .B \-\-pkcs12 file
diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index 93d81e2..ac6818e 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -486,12 +486,12 @@ init_ssl (const struct options *options, struct 
tls_root_ctx *new_ctx)
 
   if (options->tls_server)
 {
-  tls_ctx_server_new(new_ctx);
+  tls_ctx_server_new(new_ctx, options->ssl_flags);
   tls_ctx_load_dh_params(new_ctx, options->dh_file, 
options->dh_file_inline);
 }
   else /* if client */
 {
-  tls_ctx_client_new(new_ctx);
+  tls_ctx_client_new(new_ctx, options->ssl_flags);
 }
 
   tls_ctx_set_options(new_ctx, options->ssl_flags);
diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h
index 9777242..b37b1e5 100644
--- a/src/openvpn/ssl_backend.h
+++ b/src/openvpn/ssl_backend.h
@@ -109,10 +109,11 @@ void tls_clear_error();
  * @return One of the TLS_VER_x constants or TLS_VER_BAD
  *  if a parse error should be flagged.
  */
-#define TLS_VER_BAD   -1
-#define TLS_VER_1_00 /* default */
-#define TLS_VER_1_11
-#define TLS_VER_1_22
+#define TLS_VER_BAD-1
+#define TLS_VER_UNSPEC  0 /* default */
+#define TLS_VER_1_0 1
+#define TLS_VER_1_1 2
+#define TLS_VER_1_2 3
 int tls_version_min_parse(const 

Re: [Openvpn-devel] [PATCH 4/4] When tls-version-min is unspecified, revert to original versioning approach.

2014-04-21 Thread James Yonan

On 21/04/2014 05:49, Gert Doering wrote:

Hi,

On Mon, Apr 21, 2014 at 01:11:05PM +0200, Arne Schwabe wrote:

Yes. But with this patch it is always turned off, keeping OpenVPN in 99%
of installations in TLS 1.0. Is there any other known case where it
breaks aside from the Tomato OpenVPN client?


http://community.openvpn.net/openvpn/ticket/385

this is the only case I know - and I blaim the openssl library on the
server side (ARM).  So for me, "default-on with a way to turn it off" would
be sufficient.  But I assume James has much more visibility...


The problem with tls-version-min is that it defaults to 1.0 even if not 
used.  We've received many reports of breakage with this approach, 
probably because setting the min to 1.0 is actually subtly different 
from the approach used before tls-version-min was implemented.


So this patch turns off tls-version-min unless it's explicit in the config.

James



Re: [Openvpn-devel] [PATCH 4/4] When tls-version-min is unspecified, revert to original versioning approach.

2014-04-21 Thread Gert Doering
Hi,

On Mon, Apr 21, 2014 at 01:11:05PM +0200, Arne Schwabe wrote:
> Yes. But with this patch it is always turned off, keeping OpenVPN in 99% 
> of installations in TLS 1.0. Is there any other known case where it 
> breaks aside from the Tomato OpenVPN client?

http://community.openvpn.net/openvpn/ticket/385

this is the only case I know - and I blaim the openssl library on the
server side (ARM).  So for me, "default-on with a way to turn it off" would
be sufficient.  But I assume James has much more visibility...

gert

-- 
USENET is *not* the non-clickable part of WWW!
   //www.muc.de/~gert/
Gert Doering - Munich, Germany g...@greenie.muc.de
fax: +49-89-35655025g...@net.informatik.tu-muenchen.de


pgpJpttBcrEr9.pgp
Description: PGP signature


Re: [Openvpn-devel] [PATCH 4/4] When tls-version-min is unspecified, revert to original versioning approach.

2014-04-21 Thread Arne Schwabe

On 21.04.2014 12:42, Gert Doering wrote:

Hi,

On Mon, Apr 21, 2014 at 12:24:30PM +0200, Steffan Karger wrote:

On 21-04-14 09:10, James Yonan wrote:

For OpenSSL, this means to use TLSv1_(client|server)_method rather
than SSLv23_(client|server)_method combined with SSL_OP_NO_x flags
for specific TLS versions to disable.

I'm not sure I understand the rationale behind this. If I don't specify
a minimum version, my maximum version changes to TLS 1.0? Could you
maybe explain the "why" for this patch?

"turn it off!", without introducing yet another config directive (or,
more precisely, "do not turn it on by default" if I read the patch right).

There seem to be some not-yet-fully-understood combinations of OpenSSL
library versions/library builds that will break 2.3.3 clients <-> git-master
servers if the TLS version negotiation patch is active, so having a way
to turn it off at run-time (if only to see if that is the problem) is
certainly useful.

Yes. But with this patch it is always turned off, keeping OpenVPN in 99% 
of installations in TLS 1.0. Is there any other known case where it 
breaks aside from the Tomato OpenVPN client?


Arne



Re: [Openvpn-devel] [PATCH 4/4] When tls-version-min is unspecified, revert to original versioning approach.

2014-04-21 Thread Gert Doering
Hi,

On Mon, Apr 21, 2014 at 12:24:30PM +0200, Steffan Karger wrote:
> On 21-04-14 09:10, James Yonan wrote:
> > For OpenSSL, this means to use TLSv1_(client|server)_method rather
> > than SSLv23_(client|server)_method combined with SSL_OP_NO_x flags
> > for specific TLS versions to disable.
> 
> I'm not sure I understand the rationale behind this. If I don't specify
> a minimum version, my maximum version changes to TLS 1.0? Could you
> maybe explain the "why" for this patch?

"turn it off!", without introducing yet another config directive (or,
more precisely, "do not turn it on by default" if I read the patch right).

There seem to be some not-yet-fully-understood combinations of OpenSSL
library versions/library builds that will break 2.3.3 clients <-> git-master
servers if the TLS version negotiation patch is active, so having a way
to turn it off at run-time (if only to see if that is the problem) is
certainly useful.

gert

-- 
USENET is *not* the non-clickable part of WWW!
   //www.muc.de/~gert/
Gert Doering - Munich, Germany g...@greenie.muc.de
fax: +49-89-35655025g...@net.informatik.tu-muenchen.de


pgpuQmOvl63hz.pgp
Description: PGP signature


Re: [Openvpn-devel] [PATCH 4/4] When tls-version-min is unspecified, revert to original versioning approach.

2014-04-21 Thread Steffan Karger
Hi,

On 21-04-14 09:10, James Yonan wrote:
> For OpenSSL, this means to use TLSv1_(client|server)_method rather
> than SSLv23_(client|server)_method combined with SSL_OP_NO_x flags
> for specific TLS versions to disable.

I'm not sure I understand the rationale behind this. If I don't specify
a minimum version, my maximum version changes to TLS 1.0? Could you
maybe explain the "why" for this patch?

-Steffan



[Openvpn-devel] [PATCH 4/4] When tls-version-min is unspecified, revert to original versioning approach.

2014-04-21 Thread James Yonan
For OpenSSL, this means to use TLSv1_(client|server)_method rather
than SSLv23_(client|server)_method combined with SSL_OP_NO_x flags
for specific TLS versions to disable.

For PolarSSL, this means to avoid calling ssl_set_min_version and
instead implicitly control the TLS version via allowed ciphersuites.

Signed-off-by: James Yonan 
---
 src/openvpn/ssl.c  |  4 ++--
 src/openvpn/ssl_backend.h  | 15 +--
 src/openvpn/ssl_openssl.c  | 31 ++-
 src/openvpn/ssl_polarssl.c | 43 +++
 4 files changed, 56 insertions(+), 37 deletions(-)

diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index b09e52b..af30641 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -486,12 +486,12 @@ init_ssl (const struct options *options, struct 
tls_root_ctx *new_ctx)

   if (options->tls_server)
 {
-  tls_ctx_server_new(new_ctx);
+  tls_ctx_server_new(new_ctx, options->ssl_flags);
   tls_ctx_load_dh_params(new_ctx, options->dh_file, 
options->dh_file_inline);
 }
   else /* if client */
 {
-  tls_ctx_client_new(new_ctx);
+  tls_ctx_client_new(new_ctx, options->ssl_flags);
 }

   tls_ctx_set_options(new_ctx, options->ssl_flags);
diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h
index 57b03df..0b41ff2 100644
--- a/src/openvpn/ssl_backend.h
+++ b/src/openvpn/ssl_backend.h
@@ -109,10 +109,11 @@ void tls_clear_error();
  * @return One of the TLS_VER_x constants or TLS_VER_BAD
  *  if a parse error should be flagged.
  */
-#define TLS_VER_BAD   -1
-#define TLS_VER_1_00 /* default */
-#define TLS_VER_1_11
-#define TLS_VER_1_22
+#define TLS_VER_BAD-1
+#define TLS_VER_UNSPEC  0
+#define TLS_VER_1_0 1 /* default */
+#define TLS_VER_1_1 2
+#define TLS_VER_1_2 3
 int tls_version_min_parse(const char *vstr, const char *extra);

 /**
@@ -127,15 +128,17 @@ int tls_version_max(void);
  * Initialise a library-specific TLS context for a server.
  *
  * @param ctx  TLS context to initialise
+ * @param ssl_flags SSLF_x flags from ssl_common.h
  */
-void tls_ctx_server_new(struct tls_root_ctx *ctx);
+void tls_ctx_server_new(struct tls_root_ctx *ctx, unsigned int ssl_flags);

 /**
  * Initialises a library-specific TLS context for a client.
  *
  * @param ctx  TLS context to initialise
+ * @param ssl_flags SSLF_x flags from ssl_common.h
  */
-void tls_ctx_client_new(struct tls_root_ctx *ctx);
+void tls_ctx_client_new(struct tls_root_ctx *ctx, unsigned int ssl_flags);

 /**
  * Frees the library-specific TLSv1 context
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index 1923230..abf39ac 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -94,22 +94,32 @@ tls_clear_error()
 }

 void
-tls_ctx_server_new(struct tls_root_ctx *ctx)
+tls_ctx_server_new(struct tls_root_ctx *ctx, unsigned int ssl_flags)
 {
+  const int tls_version_min = (ssl_flags >> SSLF_TLS_VERSION_SHIFT) & 
SSLF_TLS_VERSION_MASK;
+
   ASSERT(NULL != ctx);

-  ctx->ctx = SSL_CTX_new (SSLv23_server_method ());
+  if (tls_version_min > TLS_VER_UNSPEC)
+ctx->ctx = SSL_CTX_new (SSLv23_server_method ());
+  else
+ctx->ctx = SSL_CTX_new (TLSv1_server_method ());

   if (ctx->ctx == NULL)
 msg (M_SSLERR, "SSL_CTX_new SSLv23_server_method");
 }

 void
-tls_ctx_client_new(struct tls_root_ctx *ctx)
+tls_ctx_client_new(struct tls_root_ctx *ctx, unsigned int ssl_flags)
 {
+  const int tls_version_min = (ssl_flags >> SSLF_TLS_VERSION_SHIFT) & 
SSLF_TLS_VERSION_MASK;
+
   ASSERT(NULL != ctx);

-  ctx->ctx = SSL_CTX_new (SSLv23_client_method ());
+  if (tls_version_min > TLS_VER_UNSPEC)
+ctx->ctx = SSL_CTX_new (SSLv23_client_method ());
+  else
+ctx->ctx = SSL_CTX_new (TLSv1_client_method ());

   if (ctx->ctx == NULL)
 msg (M_SSLERR, "SSL_CTX_new SSLv23_client_method");
@@ -182,16 +192,19 @@ tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned 
int ssl_flags)
   {
 long sslopt = SSL_OP_SINGLE_DH_USE | SSL_OP_NO_TICKET | SSL_OP_NO_SSLv2 | 
SSL_OP_NO_SSLv3;
 const int tls_version_min = (ssl_flags >> SSLF_TLS_VERSION_SHIFT) & 
SSLF_TLS_VERSION_MASK;
-if (tls_version_min > TLS_VER_1_0)
-  sslopt |= SSL_OP_NO_TLSv1;
+if (tls_version_min > TLS_VER_UNSPEC)
+  {
+   if (tls_version_min > TLS_VER_1_0)
+ sslopt |= SSL_OP_NO_TLSv1;
 #ifdef SSL_OP_NO_TLSv1_1
-if (tls_version_min > TLS_VER_1_1)
-  sslopt |= SSL_OP_NO_TLSv1_1;
+   if (tls_version_min > TLS_VER_1_1)
+ sslopt |= SSL_OP_NO_TLSv1_1;
 #endif
 #ifdef SSL_OP_NO_TLSv1_2
 if (tls_version_min > TLS_VER_1_2)
-  sslopt |= SSL_OP_NO_TLSv1_2;
+   sslopt |= SSL_OP_NO_TLSv1_2;
 #endif
+  }
 SSL_CTX_set_options (ctx->ctx, sslopt);
   }

diff --git a/src/openvpn/ssl_polarssl.c b/src/openvpn/ssl_polarssl.c
index c110d0d..15450ff 100644
---