>From James Yonan <ja...@openvpn.net>: > 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