Re: [Openvpn-devel] OpenVPN Versioning

2013-06-19 Thread James Yonan

On 18/06/2013 01:41, Joachim Schipper wrote:

From: James Yonan :

On 14/06/2013 02:47, Joachim Schipper wrote:

>From James Yonan :

TLS Protocol


Since day 1, OpenVPN has used TLS 1.0 as a control channel and key
exchange mechanism.  But now we have TLS 1.1 and 1.2, each of which
addresses significant shortcomings in its predecessor.  Fortunately,
SSL/TLS already includes dynamic version negotiation.  So I've put
together a patch that leverages on this, by allowing OpenVPN client
and server to negotiate the TLS version and use the highest version
supported by both peers.  The patch also adds a new directive "tls-
version-min" that allows either client or server to specify a

minimum

required TLS version from the peer.



https://github.com/jamesyonan/openvpn/commit/6ee8faade224cc346d67a7f1

7
1
6df4012782999a


[snip: SSL negotiation. Thanks for the explanation; I agree that speaking
the highest supported protocol is good.]


I'm not sure what purpose the "or-highest" serves. Clients already

connect with the newest protocol supported by both client and server;
if you want to run a TLSv1.2-only network, just set min-version to 1.2
on the server. (...)

Suppose a server admin wants to upgrade to TLS 1.2 over some transition
period, to allow time to upgrade existing clients in the field.



The overall goal here is to provide tools that allow a controlled
rollout of TLS 1.2 that doesn't break any clients during the rollout
period, and to upgrade to 1.2 in a way that doesn't create the
potential for MiTM version rollback attacks.


But no modern SSL protocol allows version rollback attacks: modern
implementations will always speak the highest supported/configured protocol
version between each other. (Only) SSLv2 allows rollback attacks, which is
why the only sane way to deal with SSLv2 in 2013 is to unconditionally
disable support.


Right, and the patch is able to unconditionally disable support for SSL 
2 and 3 since these were never supported by even the earliest versions 
of OpenVPN.



The switch(tls_version_min) needs a default case, just compile the

first case/default: unconditionally.

There is a default case already -- it's right under "case
TLS_VER_1_0:".


Yes, but that's #ifdef'ed. I'd be happier if the default case remained
present even if PolarSSL foolishly decides to drop TLSv1 support.


Agreed -- there shouldn't be any implicit assumption
that SSL lib might not implement TLS 1.0.

https://github.com/jamesyonan/openvpn/commit/d23005413b0e0f28a3c48a6342f494763d5c9b40


[snip: ciphersuites]

Negotiating ciphers might be fatal in some configurations that were a
bad idea to begin with. E.g. if you use OpenVPN with a static key and
--auth none (which is a bad idea!), adding this negotation could

allow

an attacker to set the cipher to none or, more dangerously, to a very
weak cipher like DES (provided it is mutually supported). An attacker
could then bruteforce the key and use his knowledge of 56 bits of the
key to attack stronger protocols like AES or 3DES. (Or do we only
negotiate in SSL mode? I must admit to being fuzzy on the non-SSL
mode.)


Static key mode has no negotiation.

Agreed that any negotiation model must have constraints placed on the
security of the negotiated cipher and HMAC digest.  You would probably
want to disable "cipher none" or "auth none" on the presumption that
users who want a cleartext tunnel would explicitly configure the client
and server for this.


Sure. Just disabling negotiations unless you have an SSL'd control channel
works fine against this.


One thing to keep in mind is that OpenVPN protocol negotiation occurs
over the already-negotiated TLS session, so it is immune to being
tampered with by a MiTM.  This is in contrast to SSL/TLS where a MiTM
can affect the negotiation.


As above, MiTM attackers cannot effect the negotiation step in SSL/TLS
protocols after SSLv2, except trivially (by causing the negotiation to fail, 
possibly a couple of protocol steps later, e.g. by dropping all packets.)


Aha, that's good to know.  Apparently browsers are still vulnerable to 
version rollback attacks due to compatibility fallback mechanisms, but 
that's great that SSL/TLS protocols are immune above SSL 3.  There's a 
good writeup on the subject here:


http://www.carbonwind.net/blog/post/Random-SSLTLS-101%E2%80%93SSLTLS-version-rollbacks-and-browsers.aspx

James



Re: [Openvpn-devel] OpenVPN Versioning

2013-06-19 Thread James Yonan

On 17/06/2013 01:58, Steffan Karger wrote:

On 06/14/2013 09:53 PM, James Yonan wrote:

To get the adaptive versioning behavior in OpenSSL, you have to use
SSLv23_server_method() or SSLv23_client_method() and then explicitly
disable the versions you don't want to consider, i.e. SSL_OP_NO_SSLv2,
SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1, SSL_OP_NO_TLSv1_1, etc.


Wow, so SSLv23_{client,server}_method() is the 'wildcard' you need to
dynamically negotiate the version. Yet it sounds like something
completely broken that should be avoided at all cost. OpenSSL keeps
amazing me.


It really shows OpenSSL's age, doesn't it?  But aside from the 
cruftiness, I wouldn't say that it's broken.  It's arguably a more 
flexible mechanism than PolarSSL because it allows you to cherry-pick 
the SSL/TLS versions you want to support, rather than just give a 
min/max range.



Does the change to key_state_ssl_init() do anything?


I had to add ssl_flags (containing tls-version-min parameter) to
key_state_ssl_init because that seems like the most appropriate place to
configure tls-version-min for PolarSSL.

For OpenSSL, tls_ctx_set_options is the right place to configure
tls-version-min.


The ssl_flags are already available through the tls session that is
passed as the fourth parameter. To make this a bit more clear, commit
b97e2c3 changed the type of session to struct tls session* (see
https://github.com/OpenVPN/openvpn/commit/b97e2c3c90afdbb1a24bc1357ec6b94d626defcd).


Right, I've rebased the patch against master and now use 
session->opt->ssl_flags


This simplifies the patch because now it's no longer necessary to pass 
ssl_flags to key_state_ssl_init


https://github.com/jamesyonan/openvpn/commit/03a5599202bdc3ba07983dc4efdae387fb8fb436

James



Re: [Openvpn-devel] OpenVPN Versioning

2013-06-18 Thread Joachim Schipper
From: James Yonan :
> On 14/06/2013 02:47, Joachim Schipper wrote:
> >>From James Yonan :
> >> TLS Protocol
> >> 
> >>
> >> Since day 1, OpenVPN has used TLS 1.0 as a control channel and key
> >> exchange mechanism.  But now we have TLS 1.1 and 1.2, each of which
> >> addresses significant shortcomings in its predecessor.  Fortunately,
> >> SSL/TLS already includes dynamic version negotiation.  So I've put
> >> together a patch that leverages on this, by allowing OpenVPN client
> >> and server to negotiate the TLS version and use the highest version
> >> supported by both peers.  The patch also adds a new directive "tls-
> >> version-min" that allows either client or server to specify a
> minimum
> >> required TLS version from the peer.
> >>
> >>
> https://github.com/jamesyonan/openvpn/commit/6ee8faade224cc346d67a7f1
> >> 7
> >> 1
> >> 6df4012782999a

[snip: SSL negotiation. Thanks for the explanation; I agree that speaking
the highest supported protocol is good.]

> > I'm not sure what purpose the "or-highest" serves. Clients already
> connect with the newest protocol supported by both client and server;
> if you want to run a TLSv1.2-only network, just set min-version to 1.2
> on the server. (...)
>
> Suppose a server admin wants to upgrade to TLS 1.2 over some transition
> period, to allow time to upgrade existing clients in the field.

> The overall goal here is to provide tools that allow a controlled
> rollout of TLS 1.2 that doesn't break any clients during the rollout
> period, and to upgrade to 1.2 in a way that doesn't create the
> potential for MiTM version rollback attacks.

But no modern SSL protocol allows version rollback attacks: modern
implementations will always speak the highest supported/configured protocol
version between each other. (Only) SSLv2 allows rollback attacks, which is
why the only sane way to deal with SSLv2 in 2013 is to unconditionally
disable support.

> > The switch(tls_version_min) needs a default case, just compile the
> first case/default: unconditionally.
>
> There is a default case already -- it's right under "case
> TLS_VER_1_0:".

Yes, but that's #ifdef'ed. I'd be happier if the default case remained
present even if PolarSSL foolishly decides to drop TLSv1 support.

[snip: ciphersuites]
> > Negotiating ciphers might be fatal in some configurations that were a
> > bad idea to begin with. E.g. if you use OpenVPN with a static key and
> > --auth none (which is a bad idea!), adding this negotation could
> allow
> > an attacker to set the cipher to none or, more dangerously, to a very
> > weak cipher like DES (provided it is mutually supported). An attacker
> > could then bruteforce the key and use his knowledge of 56 bits of the
> > key to attack stronger protocols like AES or 3DES. (Or do we only
> > negotiate in SSL mode? I must admit to being fuzzy on the non-SSL
> > mode.)
>
> Static key mode has no negotiation.
>
> Agreed that any negotiation model must have constraints placed on the
> security of the negotiated cipher and HMAC digest.  You would probably
> want to disable "cipher none" or "auth none" on the presumption that
> users who want a cleartext tunnel would explicitly configure the client
> and server for this.

Sure. Just disabling negotiations unless you have an SSL'd control channel
works fine against this.

> One thing to keep in mind is that OpenVPN protocol negotiation occurs
> over the already-negotiated TLS session, so it is immune to being
> tampered with by a MiTM.  This is in contrast to SSL/TLS where a MiTM
> can affect the negotiation.

As above, MiTM attackers cannot effect the negotiation step in SSL/TLS
protocols after SSLv2, except trivially (by causing the negotiation to fail, 
possibly a couple of protocol steps later, e.g. by dropping all packets.)

Joachim



Re: [Openvpn-devel] OpenVPN Versioning

2013-06-17 Thread Steffan Karger
On 06/14/2013 09:53 PM, James Yonan wrote:
> To get the adaptive versioning behavior in OpenSSL, you have to use 
> SSLv23_server_method() or SSLv23_client_method() and then explicitly 
> disable the versions you don't want to consider, i.e. SSL_OP_NO_SSLv2, 
> SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1, SSL_OP_NO_TLSv1_1, etc.
> 
Wow, so SSLv23_{client,server}_method() is the 'wildcard' you need to
dynamically negotiate the version. Yet it sounds like something
completely broken that should be avoided at all cost. OpenSSL keeps
amazing me.

>> Does the change to key_state_ssl_init() do anything?
> 
> I had to add ssl_flags (containing tls-version-min parameter) to 
> key_state_ssl_init because that seems like the most appropriate place to 
> configure tls-version-min for PolarSSL.
> 
> For OpenSSL, tls_ctx_set_options is the right place to configure 
> tls-version-min.
> 
The ssl_flags are already available through the tls session that is
passed as the fourth parameter. To make this a bit more clear, commit
b97e2c3 changed the type of session to struct tls session* (see
https://github.com/OpenVPN/openvpn/commit/b97e2c3c90afdbb1a24bc1357ec6b94d626defcd).

-Steffan




Re: [Openvpn-devel] OpenVPN Versioning

2013-06-14 Thread Joachim Schipper
>From James Yonan :
> TLS Protocol
> 
>
> Since day 1, OpenVPN has used TLS 1.0 as a control channel and key
> exchange mechanism.  But now we have TLS 1.1 and 1.2, each of which
> addresses significant shortcomings in its predecessor.  Fortunately,
> SSL/TLS already includes dynamic version negotiation.  So I've put
> together a patch that leverages on this, by allowing OpenVPN client
> and server to negotiate the TLS version and use the highest version
> supported by both peers.  The patch also adds a new directive "tls-
> version-min" that allows either client or server to specify a minimum
> required TLS version from the peer.
>
> https://github.com/jamesyonan/openvpn/commit/6ee8faade224cc346d67a7f17
> 1
> 6df4012782999a

Some comments on the design and implementation here. (I've just looked at the 
code, not tested it.)

I'm confused by your comments about TLS/SSL versions used. Our own builds using 
PolarSSL do negotiate TLSv1.1 and TLSv1.2 between themselves and when 
interoperating with OpenSSL, logging "Control Channel: TLSv1.1, cipher XXX" or 
even "Control Channel: TLSv1.2, cipher XXX". In general, the highest version 
supported by both client and server is used, as is normally the case with SSL. 
However, stock Ubuntu OpenVPN seems to negotiate TLSv1. Huh?

I'm not sure what purpose the "or-highest" serves. Clients already connect with 
the newest protocol supported by both client and server; if you want to run a 
TLSv1.2-only network, just set min-version to 1.2 on the server. If you're an 
especially competent and paranoid user, you might want to set min-version on 
the client, but in that case you hardly need an "or-highest", since you know 
which cipher suites your client supports.

Some of the whitespace looks odd/wrong.

Does the change to key_state_ssl_init() do anything?

The variables polar_{major,minor} in ssl_polarssl.c should be renamed, probably 
to something like ssl_{major,minor}_version - it's not a PolarSSL version.

The switch(tls_version_min) needs a default case, just compile the first 
case/default: unconditionally.

> OpenVPN Protocol
> 

> [Handshaking] could be used to negotiate other protocol capabilities
> such as cipher and HMAC digest:
>
>IV_CIPHER=BF-CBC,AES-128-CBC
>IV_AUTH=SHA1,SHA256,SHA512
>
> (...) There
> is also the issue of the size of the Client Capabilities List.  The
> IV_CIPHER and IV_AUTH lists might grow to be quite long (...) To
> reduce the size, we might
> consider:
>
> (a) use a single character designation for ciphers and HMAC digests,
> such as:
>
> Cipher Codes:
>   A : BF-CBC
>   B : AES-128-CBC
>   . . .
>
> Then communicate IV_CIPHER using the cipher codes:
>
>IV_CIPHER=AB
>
> This would require that the OpenVPN Project standardize on set of
> codes for ciphers and HMAC digests.

This is a good idea in general, but why not use SSL cipher suites (which 
already have standardized binary representations)? That has the added advantage 
of itting AEAD suites like AES-GCM, which are getting more important. (We may 
need to add some, but note that the { 0xff, X } "namespace" is available for 
"local and experimental" cipher suites.)

Negotiating ciphers might be fatal in some configurations that were a bad idea 
to begin with. E.g. if you use OpenVPN with a static key and --auth none (which 
is a bad idea!), adding this negotation could allow an attacker to set the 
cipher to none or, more dangerously, to a very weak cipher like DES (provided 
it is mutually supported). An attacker could then bruteforce the key and use 
his knowledge of 56 bits of the key to attack stronger protocols like AES or 
3DES. (Or do we only negotiate in SSL mode? I must admit to being fuzzy on the 
non-SSL mode.)

Joachim



Re: [Openvpn-devel] OpenVPN Versioning

2013-06-12 Thread James Yonan

On 12/06/2013 15:08, Arne Schwabe wrote:

Am 12.06.13 21:38, schrieb James Yonan:

About finding out which cipher client and server use. I am not really
familiar with this code so forgive my stupid question. TLS somehow also
does this "select the best cipher to use" dance. Why can't we use the
TLS mechanism but have to use our own IV_CIPHER?


TLS includes a handshake mechanism for TLS version and ciphersuite 
selection.  In TLS, a single ciphersuite specifies a set of cipher, 
mode, keysize, MAC digest, etc., while in OpenVPN the cipher and HMAC 
digest are separately selected by cipher and auth directives.


Historically, OpenVPN has never implemented any interaction between the 
TLS ciphersuite selection and the cipher/auth selection for the OpenVPN 
protocol -- they are completely decoupled from one another, so using TLS 
negotiation isn't going to have any effect on OpenVPN cipher/auth.


But you raise an interesting point that we might want to explore, i.e. 
looking at the TLS ciphersuite that ends up getting negotiated, and 
extract the cipher/auth directive from that since you know it will be 
consistent on both client and server.



Suppose I want to put this directive in the config files I distribute to
clients, but have it be ignored by older clients that don't recognize
it.  I could do this as follows on the client:

setenv opt tls-version-min 1.2

I suppose this a good idea too also support older client. I would to
*additionally* add a way to support this in a nicer way for future
release. Like also adding an option

ignore-unknown-options tls-version new-cool-option

so newer can some day can still be written with having to use "setenv opt"


Sure, that makes sense.


Loosly related this would also allow to give use a "default" set of
options that can be ignored (ip-win32 on *nix)


Deciding whether or not to ignore options is tricky.  With the new 3.0 
core, it was necessary to ignore some options because they are simply 
not implemented, and raising an error for every unimplemented option 
would make it very difficult upgrade to 3.0 in a way that maintains 
reasonable config file compatibility with 2.x.


So the approach I took for 3.0 was to only raise an error on 
unimplemented options where ignoring the option might compromise 
security.  Initially tls-remote fell under this category, but it has 
since been implemented in the 3.0 core.


James