summaryrefslogtreecommitdiffstats
path: root/src/openvpn/ssl_openssl.c
diff options
context:
space:
mode:
authorJames Yonan <james@openvpn.net>2013-06-10 22:59:30 -0600
committerDavid Sommerseth <davids@redhat.com>2013-07-11 21:00:20 +0200
commit4b67f9849ab3efe89268e01afddc7795f38d0f64 (patch)
tree10a9e63eef0f83ae032441c582d98f15a7d6399e /src/openvpn/ssl_openssl.c
parent8065cd1c65273ef05ba2ac66f15224e170a57290 (diff)
downloadopenvpn-4b67f9849ab3efe89268e01afddc7795f38d0f64.tar.gz
openvpn-4b67f9849ab3efe89268e01afddc7795f38d0f64.tar.xz
openvpn-4b67f9849ab3efe89268e01afddc7795f38d0f64.zip
TLS version negotiation
Updated the TLS negotiation logic to adaptively try to connect using the highest TLS version supported by both client and server. Previously, OpenVPN (when linked with OpenSSL) would always connect using TLS 1.0. Also added tls-version-min directive to force a higher TLS version than 1.0: tls-version-min <version> ['or-highest'] -- sets the minimum TLS version we will accept from the peer. Examples for version include "1.0" (default), "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. Examples: tls-version-min 1.1 -- fail the connection unless peer can connect at TLS 1.1 or higher. tls-version-min 1.2 or-highest -- require that the peer connect at TLS 1.2 or higher, however if the local SSL implementation doesn't support TLS 1.2 (as it wouldn't if linked with an older version of OpenSSL), reduce the minimum required version to the highest version supported by the local SSL implementation (such as TLS 1.0). This is intended to allow client configurations to target higher TLS versions that are supported on the server, even if some older clients don't support these versions yet. [ This is a merged patch from on the following commits on git://github.com/jamesyonan/openvpn.git 03a5599202bdc3ba07983dc4efdae387fb8fb436 d23005413b0e0f28a3c48a6342f494763d5c9b40 ] Signed-off-by: James Yonan <james@openvpn.net> Acked-by: Gert Doering <gert@greenie.muc.de> Acked-by: Arne Schwabe <arne@rfc2549.org> URL: http://thread.gmane.org/gmane.network.openvpn.devel/7743 URL: http://thread.gmane.org/gmane.network.openvpn.devel/7744 Message-Id: 51C77F12.1090802@openvpn.net Signed-off-by: David Sommerseth <davids@redhat.com>
Diffstat (limited to 'src/openvpn/ssl_openssl.c')
-rw-r--r--src/openvpn/ssl_openssl.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index 5db717d..12c725d 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -114,7 +114,7 @@ tls_ctx_server_new(struct tls_root_ctx *ctx)
{
ASSERT(NULL != ctx);
- ctx->ctx = SSL_CTX_new (TLSv1_server_method ());
+ ctx->ctx = SSL_CTX_new (SSLv23_server_method ());
if (ctx->ctx == NULL)
msg (M_SSLERR, "SSL_CTX_new TLSv1_server_method");
@@ -127,7 +127,7 @@ tls_ctx_client_new(struct tls_root_ctx *ctx)
{
ASSERT(NULL != ctx);
- ctx->ctx = SSL_CTX_new (TLSv1_client_method ());
+ ctx->ctx = SSL_CTX_new (SSLv23_client_method ());
if (ctx->ctx == NULL)
msg (M_SSLERR, "SSL_CTX_new TLSv1_client_method");
@@ -174,13 +174,46 @@ info_callback (INFO_CALLBACK_SSL_CONST SSL * s, int where, int ret)
}
}
+/*
+ * Return maximum TLS version supported by local OpenSSL library.
+ * Assume that presence of SSL_OP_NO_TLSvX macro indicates that
+ * TLSvX is supported.
+ */
+int
+tls_version_max(void)
+{
+#if defined(SSL_OP_NO_TLSv1_2)
+ return TLS_VER_1_2;
+#elif defined(SSL_OP_NO_TLSv1_1)
+ return TLS_VER_1_1;
+#else
+ return TLS_VER_1_0;
+#endif
+}
+
void
tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags)
{
ASSERT(NULL != ctx);
+ /* process SSL options including minimum TLS version we will accept from peer */
+ {
+ long sslopt = SSL_OP_SINGLE_DH_USE | 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;
+#ifdef 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;
+#endif
+ SSL_CTX_set_options (ctx->ctx, sslopt);
+ }
+
SSL_CTX_set_session_cache_mode (ctx->ctx, SSL_SESS_CACHE_OFF);
- SSL_CTX_set_options (ctx->ctx, SSL_OP_SINGLE_DH_USE);
SSL_CTX_set_default_passwd_cb (ctx->ctx, pem_password_callback);
/* Require peer certificate verification */