From patchwork Fri Mar 27 17:08:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arne Schwabe X-Patchwork-Id: 1055 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director9.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id GAcGFzTOfl7UagAAIUCqbw for ; Sat, 28 Mar 2020 00:10:28 -0400 Received: from proxy14.mail.ord1d.rsapps.net ([172.30.191.6]) by director9.mail.ord1d.rsapps.net with LMTP id gLX0FjTOfl7xdgAAalYnBA ; Sat, 28 Mar 2020 00:10:28 -0400 Received: from smtp26.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy14.mail.ord1d.rsapps.net with LMTP id CCymFjTOfl7eZgAAtEH5vw ; Sat, 28 Mar 2020 00:10:28 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp26.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=rfc2549.org X-Suspicious-Flag: YES X-Classification-ID: 0e32ba62-70aa-11ea-b8e4-525400c5b129-1-1 Received: from [216.105.38.7] ([216.105.38.7:37820] helo=lists.sourceforge.net) by smtp26.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id D0/3D-25958-33ECE7E5; Sat, 28 Mar 2020 00:10:28 -0400 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1jI2mh-00058e-EZ; Sat, 28 Mar 2020 04:09:23 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jI2md-00058D-Vl for openvpn-devel@lists.sourceforge.net; Sat, 28 Mar 2020 04:09:19 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc: MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=IJSBDM5jvucIE3kOAejYFHq/hWOM+OqU7O/wy/p7TjM=; b=TGx7oXse1Zx3mDXjS2UAglRNtE 2zL7TTlRtie3Ot53oZF/UXPe+XMi5suweE50eKV8xRurv/foaL+Mx1LDgzWGzhF7DIjsVtunOvhbc r8QyG5RMCbvzI5OyyqScKKLT4HTfVrw+MQofSgVrjW4veskzWC8djYyzfGuTBfbY36mY=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:MIME-Version: Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=IJSBDM5jvucIE3kOAejYFHq/hWOM+OqU7O/wy/p7TjM=; b=BcwcQOY0H62/ggYTbJNJyTBQUp CSewv7niS8n4ihL4lSzHu2CWS5c+KDTpLuWVrOjqnqIQnG+/hRWj35k91e4dySxkhZMIP6WHQAhaR C9sCPkjSMOYt1Avp1ZcP6TeYD4iIF/vKhKLf5CWAIPTvfMSPaRgxvjFpcX3LQWWpsUi4=; Received: from mail.blinkt.de ([192.26.174.232]) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jI2mY-007L1t-JN for openvpn-devel@lists.sourceforge.net; Sat, 28 Mar 2020 04:09:19 +0000 Received: from kamera.blinkt.de ([2001:638:502:390:20c:29ff:fec8:535c]) by mail.blinkt.de with smtp (Exim 4.92.3 (FreeBSD)) (envelope-from ) id 1jI2mK-0001oi-4J for openvpn-devel@lists.sourceforge.net; Sat, 28 Mar 2020 05:09:00 +0100 Received: (nullmailer pid 16552 invoked by uid 10006); Sat, 28 Mar 2020 04:08:58 -0000 From: Arne Schwabe To: openvpn-devel@lists.sourceforge.net Date: Sat, 28 Mar 2020 05:08:58 +0100 Message-Id: <20200328040858.16505-1-arne@rfc2549.org> X-Mailer: git-send-email 2.17.1 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.2 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1jI2mY-007L1t-JN Subject: [Openvpn-devel] [PATCH] Fix OpenSSL 1.1.1 not using auto ecliptic curve selection X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox Commit 8a01147ff attempted to avoid calling the deprecated/noop operation SSL_CTX_set_ecdh_auto by surrounding it with #ifdef. Unfortunately, that change also made the return; that would exit the function no longer being compiled when using OpenSSL 1.1.0+. As consequence OpenVPN with OpenSSL 1.1.0+ would always set secp384r1 as ecdh curve unless otherwise specified by ecdh This patch restores the correct/previous behaviour. Acked-by: Antonio Quartulli --- src/openvpn/ssl_openssl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index 3f0031ff..4b5ca214 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -678,8 +678,11 @@ tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name /* OpenSSL 1.0.2 and newer can automatically handle ECDH parameter * loading */ SSL_CTX_set_ecdh_auto(ctx->ctx, 1); - return; + + /* OpenSSL 1.1.0 and newer have always ecdh auto loading enabled, + * so do nothing */ #endif + return; #else /* For older OpenSSL we have to extract the curve from key on our own */ EC_KEY *eckey = NULL; From patchwork Tue Mar 31 23:21:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arne Schwabe X-Patchwork-Id: 1063 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director12.mail.ord1d.rsapps.net ([172.31.255.6]) by backend30.mail.ord1d.rsapps.net with LMTP id 6OttGJZrhF6iVwAAIUCqbw for ; Wed, 01 Apr 2020 06:23:18 -0400 Received: from proxy19.mail.iad3b.rsapps.net ([172.31.255.6]) by director12.mail.ord1d.rsapps.net with LMTP id 4D24FZZrhF6VVQAAIasKDg ; Wed, 01 Apr 2020 06:23:18 -0400 Received: from smtp35.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy19.mail.iad3b.rsapps.net with LMTP id sIg/D5ZrhF7PcwAAIG4riQ ; Wed, 01 Apr 2020 06:23:18 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp35.gate.iad3b.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=rfc2549.org X-Suspicious-Flag: YES X-Classification-ID: cd3a8aba-7402-11ea-b69d-525400503131-1-1 Received: from [216.105.38.7] ([216.105.38.7:35448] helo=lists.sourceforge.net) by smtp35.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 3E/9D-22416-59B648E5; Wed, 01 Apr 2020 06:23:17 -0400 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1jJaVr-0006B7-32; Wed, 01 Apr 2020 10:22:23 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jJaVp-0006Ag-KG for openvpn-devel@lists.sourceforge.net; Wed, 01 Apr 2020 10:22:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=References:In-Reply-To:Message-Id:Date:Subject:To: From:Sender:Reply-To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=ANfuXk0DxNcKG/qholHcTXDLGEjYwiXswi24+aicNps=; b=IN17znKxYPJhXwqF2HLapmVSZT VP94EjI3DuyoavDxCbJjppH2q9CWxdPvHQTNdAZaUTOF0RR6i2zX54C4PROunUSe4VCtT8QDeDy1q gxU+tHNmmUUUfLRZbdLHC30hHvlwpxlSxbUHkCmBlEUYbsFSVgwjbW6ot0anJO7+UcCA=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=References:In-Reply-To:Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc :MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=ANfuXk0DxNcKG/qholHcTXDLGEjYwiXswi24+aicNps=; b=Xn9vV4v4bX9qUUAQ1KQbHCOv9A dP3y94nzAjIrq/u6rMIKZ4fLoMwmzA7GKJliWVYiu5/25CcB8WR3oufZFm05xRQXi9Wf47zwIubQR fbfq15jY4fPZNJFZIsQhhr8jSj65rwzYvpAlTe/eAkUh7Ldx038EEzrhztfVsubD/dTw=; Received: from mail.blinkt.de ([192.26.174.232]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jJaVi-00FLz0-Mf for openvpn-devel@lists.sourceforge.net; Wed, 01 Apr 2020 10:22:21 +0000 Received: from kamera.blinkt.de ([2001:638:502:390:20c:29ff:fec8:535c]) by mail.blinkt.de with smtp (Exim 4.92.3 (FreeBSD)) (envelope-from ) id 1jJaVT-000HuX-HZ for openvpn-devel@lists.sourceforge.net; Wed, 01 Apr 2020 12:21:59 +0200 Received: (nullmailer pid 29202 invoked by uid 10006); Wed, 01 Apr 2020 10:21:59 -0000 From: Arne Schwabe To: openvpn-devel@lists.sourceforge.net Date: Wed, 1 Apr 2020 12:21:58 +0200 Message-Id: <20200401102159.29157-1-arne@rfc2549.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200328040858.16505-1-arne@rfc2549.org> References: <20200328040858.16505-1-arne@rfc2549.org> X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.5 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1jJaVi-00FLz0-Mf Subject: [Openvpn-devel] [PATCH 2/3] Refactor counting number of element in a : delimited list into function X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox --- src/openvpn/misc.c | 18 ++++++++++++++++++ src/openvpn/misc.h | 13 +++++++++++++ src/openvpn/ssl_mbedtls.c | 15 ++------------- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c index 1931149b..b375451f 100644 --- a/src/openvpn/misc.c +++ b/src/openvpn/misc.c @@ -735,4 +735,22 @@ output_peer_info_env(struct env_set *es, const char *peer_info) } } +int get_num_elements(const char* string, char delimiter) +{ + int string_len = strlen(string); + + ASSERT(0 != string_len); + + int element_count = 1; + /* Get number of ciphers */ + for (int i = 0; i < string_len; i++) + { + if (string[i] == delimiter) + { + element_count++; + } + } + + return element_count; +} #endif /* P2MP_SERVER */ diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h index 991b7df2..0655b7fe 100644 --- a/src/openvpn/misc.h +++ b/src/openvpn/misc.h @@ -175,4 +175,17 @@ void output_peer_info_env(struct env_set *es, const char *peer_info); #endif /* P2MP_SERVER */ +/** + * Counts the number of delimiter in a string and returns + * their number +1. This is typically used to find out the + * number elements in a cipher string or similar that is separated by : like + * + * X25519:secp256r1:X448:secp512r1:secp384r1:brainpoolP384r1 + * + * @param string the string to work on + * @param delimiter the delimiter to count, typically ':' + * @return number of delimiter found + 1 + */ +int +get_num_elements(const char* string, char delimiter); #endif /* ifndef MISC_H */ diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c index 0f0b035b..0e17e734 100644 --- a/src/openvpn/ssl_mbedtls.c +++ b/src/openvpn/ssl_mbedtls.c @@ -289,33 +289,22 @@ void tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) { char *tmp_ciphers, *tmp_ciphers_orig, *token; - int i, cipher_count; - int ciphers_len; if (NULL == ciphers) { return; /* Nothing to do */ - } - ciphers_len = strlen(ciphers); ASSERT(NULL != ctx); - ASSERT(0 != ciphers_len); /* Get number of ciphers */ - for (i = 0, cipher_count = 1; i < ciphers_len; i++) - { - if (ciphers[i] == ':') - { - cipher_count++; - } - } + int cipher_count = get_num_elements(ciphers, ':'); /* Allocate an array for them */ ALLOC_ARRAY_CLEAR(ctx->allowed_ciphers, int, cipher_count+1) /* Parse allowed ciphers, getting IDs */ - i = 0; + int i = 0; tmp_ciphers_orig = tmp_ciphers = string_alloc(ciphers, NULL); token = strtok(tmp_ciphers, ":"); From patchwork Tue Mar 31 23:21:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arne Schwabe X-Patchwork-Id: 1064 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director12.mail.ord1d.rsapps.net ([172.31.255.6]) by backend30.mail.ord1d.rsapps.net with LMTP id 2BHJH5drhF5PPwAAIUCqbw for ; Wed, 01 Apr 2020 06:23:19 -0400 Received: from proxy10.mail.iad3b.rsapps.net ([172.31.255.6]) by director12.mail.ord1d.rsapps.net with LMTP id KBkkHZdrhF6yVwAAIasKDg ; Wed, 01 Apr 2020 06:23:19 -0400 Received: from smtp5.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy10.mail.iad3b.rsapps.net with LMTP id gOVpF5drhF7kBwAA/F5p9A ; Wed, 01 Apr 2020 06:23:19 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp5.gate.iad3b.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=rfc2549.org X-Suspicious-Flag: YES X-Classification-ID: cd63315e-7402-11ea-8b75-525400155d63-1-1 Received: from [216.105.38.7] ([216.105.38.7:45444] helo=lists.sourceforge.net) by smtp5.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 3E/73-10965-59B648E5; Wed, 01 Apr 2020 06:23:18 -0400 Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1jJaVq-0000uG-KT; Wed, 01 Apr 2020 10:22:22 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jJaVo-0000u7-Py for openvpn-devel@lists.sourceforge.net; Wed, 01 Apr 2020 10:22:20 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=References:In-Reply-To:Message-Id:Date:Subject:To: From:Sender:Reply-To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=noRYbWWbLu8Vx24gw6toWkS6lC6UzhV9TAdgaIL77os=; b=DhKrXyrsPpmMT4vZGPGXJiOBgB /odNFLTNQfkJPGDLHN7YEP/TUZDhtEsiWJP+5WZSzf/RTK+LxkJespy9W+O/w0ksgGb5WhpZd3m4R OXJ2lpXx4fvJTsUNXq08OJfb5yMPlfEakDDW7WTXxQTJ5EUAP2dMOR0zDkzWuvQuyrKk=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=References:In-Reply-To:Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc :MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=noRYbWWbLu8Vx24gw6toWkS6lC6UzhV9TAdgaIL77os=; b=iV/nDBh9/2PuWAKaaud16fKctL NIvCTd6r/1QgkMSW30KdNSYnzJjhiw6gBZIkC9wRmcFznaTMqx7x+uSaiUsOAVyDxVaTX9DfIgQih ecSePCj7tuZi/2NUPY2in93KIgYAkwrhmLR7Pahan9jibhr9mEY+Im0olPev4IkT7X64=; Received: from [192.26.174.232] (helo=mail.blinkt.de) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jJaVk-000F7m-57 for openvpn-devel@lists.sourceforge.net; Wed, 01 Apr 2020 10:22:20 +0000 Received: from kamera.blinkt.de ([2001:638:502:390:20c:29ff:fec8:535c]) by mail.blinkt.de with smtp (Exim 4.92.3 (FreeBSD)) (envelope-from ) id 1jJaVT-000Hua-Kl for openvpn-devel@lists.sourceforge.net; Wed, 01 Apr 2020 12:21:59 +0200 Received: (nullmailer pid 29205 invoked by uid 10006); Wed, 01 Apr 2020 10:21:59 -0000 From: Arne Schwabe To: openvpn-devel@lists.sourceforge.net Date: Wed, 1 Apr 2020 12:21:59 +0200 Message-Id: <20200401102159.29157-2-arne@rfc2549.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200401102159.29157-1-arne@rfc2549.org> References: <20200328040858.16505-1-arne@rfc2549.org> <20200401102159.29157-1-arne@rfc2549.org> X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 1.0 RDNS_NONE Delivered to internal network by a host with no rDNS X-Headers-End: 1jJaVk-000F7m-57 Subject: [Openvpn-devel] [PATCH 3/3] Implement tls-groups option to specify eliptic curves/groups X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox OpenSSL 1.1+ by default only allows signatures and key exchange from the default list of X25519:secp256r1:X448:secp521r1:secp384r1. Since in TLS1.3 key exchange is independent from the signature/key of the certificates, allowing all groups per default is not a sensible choice anymore and the shorter lister is reasonable. However, when using certificates with exotic curves the signatures of this certificates will no longer be accepted. This option allows to modify the list for these corner cases. Signed-off-by: Arne Schwabe --- README.ec | 7 +-- doc/openvpn.8 | 37 +++++++++++-- src/openvpn/openssl_compat.h | 4 ++ src/openvpn/options.c | 10 +++- src/openvpn/options.h | 1 + src/openvpn/ssl.c | 6 +++ src/openvpn/ssl_backend.h | 10 ++++ src/openvpn/ssl_mbedtls.c | 47 ++++++++++++++++ src/openvpn/ssl_mbedtls.h | 1 + src/openvpn/ssl_openssl.c | 101 +++++++++++++++++++++++++++-------- 10 files changed, 194 insertions(+), 30 deletions(-) diff --git a/README.ec b/README.ec index 32938017..2f830972 100644 --- a/README.ec +++ b/README.ec @@ -12,14 +12,15 @@ OpenVPN 2.4.0 and newer automatically initialize ECDH parameters. When ECDSA is used for authentication, the curve used for the server certificate will be used for ECDH too. When autodetection fails (e.g. when using RSA certificates) OpenVPN lets the crypto library decide if possible, or falls back to the -secp384r1 curve. +secp384r1 curve. The list of groups/curves that the crypto library will choose +from can be set with the --tls-groups configuration. An administrator can force an OpenVPN/OpenSSL server to use a specific curve using the --ecdh-curve option with one of the curves listed as -available by the --show-curves option. Clients will use the same curve as +available by the --show-groups option. Clients will use the same curve as selected by the server. -Note that not all curves listed by --show-curves are available for use with TLS; +Note that not all curves listed by --show-groups are available for use with TLS; in that case connecting will fail with a 'no shared cipher' TLS error. Authentication (ECDSA) diff --git a/doc/openvpn.8 b/doc/openvpn.8 index c5b16981..4897fbdb 100644 --- a/doc/openvpn.8 +++ b/doc/openvpn.8 @@ -5084,11 +5084,11 @@ simply supplied to the crypto library. Please see the OpenSSL and/or mbed TLS documentation for details on the cipher list interpretation. For OpenSSL, the -.B \-\-tls-cipher +.B \-\-tls\-cipher is used for TLS 1.2 and below. For TLS 1.3 and up, the .B \-\-tls\-ciphersuites setting is used. mbed TLS has no TLS 1.3 support yet and only the -.B \-\-tls-cipher +.B \-\-tls\-cipher setting is used. Use @@ -5096,6 +5096,8 @@ Use to see a list of TLS ciphers supported by your crypto library. Warning! +.B \-\-tls\-groups +, .B \-\-tls\-cipher and .B \-\-tls\-ciphersuites @@ -5111,6 +5113,33 @@ OpenSSL. The default for \-\-tls\-ciphersuites is to use the crypto library's default. .\"********************************************************* .TP +.B \-\-tls\-groups l +A list +.B l +of allowable groups/curves in order of preference. + +Set the allowed elictipic curves/groups for the TLS session. +These groups are allowed to be used in signatures and key exchange. + +mbed TLS currently allows all known curves per default. + +OpenSSL 1.1+ restricts the list per default to +"X25519:secp256r1:X448:secp521r1:secp384r1". + +If you use certificates that use non-standard curves, you +might need to add them here. If you do not force the ecdh curve +by using +.B \-\-ecdh\-curve +, the groups for ecdh will also be picked from this list. + +OpenVPN maps the curve name secp256r1 to prime256v1 to allow +specifying the tls-groups option for mbed TLS and OpenSSL. + +Warning: this option not only affects eliptic curve certificates +but also the key exchange in TLS 1.3 and using this option improperly +will disable TLS 1.3. +.\"********************************************************* +.TP .B \-\-tls\-cert\-profile profile Set the allowed cryptographic algorithms for certificates according to .B profile\fN. @@ -5876,8 +5905,10 @@ engines supported by the OpenSSL library. .TP .B \-\-show\-curves (Standalone) -Show all available elliptic curves to use with the +Show all available elliptic groups/curves to use with the .B \-\-ecdh\-curve +and +.B \-\-tls\-groups option. .\"********************************************************* .SS Generating key material: diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index 4ac8f24d..352e79f9 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -807,4 +807,8 @@ SSL_CTX_set_max_proto_version(SSL_CTX *ctx, long tls_ver_max) } #endif /* SSL_CTX_set_max_proto_version */ +#ifndef SSL_CTX_set1_groups +#define SSL_CTX_set1_groups SSL_CTX_set1_curves +#endif + #endif /* OPENSSL_COMPAT_H_ */ diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 5127f653..88f4051e 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -7894,7 +7894,7 @@ add_option(struct options *options, VERIFY_PERMISSION(OPT_P_GENERAL); options->show_tls_ciphers = true; } - else if (streq(p[0], "show-curves") && !p[1]) + else if ((streq(p[0], "show-curves") || streq(p[0], "show-groups")) && !p[1]) { VERIFY_PERMISSION(OPT_P_GENERAL); options->show_curves = true; @@ -7902,6 +7902,9 @@ add_option(struct options *options, else if (streq(p[0], "ecdh-curve") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_GENERAL); + msg(M_WARN, "Consider setting groups/curves in preference with " + "tls-groups instead of forcing a specific curve with " + "ecdh-curve."); options->ecdh_curve = p[1]; } else if (streq(p[0], "tls-server") && !p[1]) @@ -8090,6 +8093,11 @@ add_option(struct options *options, VERIFY_PERMISSION(OPT_P_GENERAL); options->cipher_list_tls13 = p[1]; } + else if (streq(p[0], "tls-groups") && p[1] && !p[2]) + { + VERIFY_PERMISSION(OPT_P_GENERAL); + options->tls_groups = p[1]; + } else if (streq(p[0], "crl-verify") && p[1] && ((p[2] && streq(p[2], "dir")) || (p[2] && streq(p[1], INLINE_FILE_TAG) ) || !p[2]) && !p[3]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 2f1f6faf..3732a3a5 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -537,6 +537,7 @@ struct options const char *pkcs12_file; const char *cipher_list; const char *cipher_list_tls13; + const char *tls_groups; const char *tls_cert_profile; const char *ecdh_curve; const char *tls_verify; diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index e21279f1..8bd1c86a 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -630,6 +630,12 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx) tls_ctx_restrict_ciphers(new_ctx, options->cipher_list); tls_ctx_restrict_ciphers_tls13(new_ctx, options->cipher_list_tls13); + /* Set the allow groups/curves for TLS if we want to override them */ + if (options->tls_groups) + { + tls_ctx_set_tls_groups(new_ctx, options->tls_groups); + } + if (!tls_ctx_set_options(new_ctx, options->ssl_flags)) { goto err; diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h index 1c244ece..d95e8320 100644 --- a/src/openvpn/ssl_backend.h +++ b/src/openvpn/ssl_backend.h @@ -198,6 +198,16 @@ void tls_ctx_restrict_ciphers_tls13(struct tls_root_ctx *ctx, const char *cipher */ void tls_ctx_set_cert_profile(struct tls_root_ctx *ctx, const char *profile); +/** + * Set the allowed (eliptic curve) group allowed for signatures and + * key exchange. + * + * @param ctx TLS context to restrict, must be valid. + * @param groups List of groups that will be allowed, in priority, + * separated by : + */ +void tls_ctx_set_tls_groups(struct tls_root_ctx *ctx, const char *groups); + /** * Check our certificate notBefore and notAfter fields, and warn if the cert is * either not yet valid or has expired. Note that this is a non-fatal error, diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c index 0e17e734..9ce68275 100644 --- a/src/openvpn/ssl_mbedtls.c +++ b/src/openvpn/ssl_mbedtls.c @@ -176,6 +176,11 @@ tls_ctx_free(struct tls_root_ctx *ctx) free(ctx->allowed_ciphers); } + if (ctx->groups) + { + free(ctx->groups); + } + CLEAR(*ctx); ctx->initialised = false; @@ -342,6 +347,43 @@ tls_ctx_set_cert_profile(struct tls_root_ctx *ctx, const char *profile) } } +void +tls_ctx_set_tls_groups(struct tls_root_ctx *ctx, const char *groups) +{ + ASSERT(NULL != ctx); + + /* Get number of groups */ + int groups_count = get_num_elements(groups, ':'); + + /* Allocate an array for them */ + ALLOC_ARRAY_CLEAR(ctx->groups, mbedtls_ecp_group_id, groups_count + 1) + + /* Parse allowed ciphers, getting IDs */ + int i = 0; + char *tmp_groups_orig = string_alloc(groups, NULL); + char *tmp_groups = tmp_groups_orig; + + const char *token = strsep(&tmp_groups, ":"); + while (token) + { + const mbedtls_ecp_curve_info *ci = + mbedtls_ecp_curve_info_from_name(token); + if (ci == NULL) + { + msg(M_WARN, "Warning unknown curve/group specified: %s", token); + } + else + { + ctx->groups[i] = ci->grp_id; + i++; + } + token = strsep(&tmp_groups, ":"); + } + ctx->groups[i] = MBEDTLS_ECP_DP_NONE; + free(tmp_groups_orig); +} + + void tls_ctx_check_cert_time(const struct tls_root_ctx *ctx) { @@ -1042,6 +1084,11 @@ key_state_ssl_init(struct key_state_ssl *ks_ssl, mbedtls_ssl_conf_ciphersuites(&ks_ssl->ssl_config, ssl_ctx->allowed_ciphers); } + if (ssl_ctx->groups) + { + mbedtls_ssl_conf_curves(&ks_ssl->ssl_config, ssl_ctx->groups); + } + /* Disable record splitting (for now). OpenVPN assumes records are sent * unfragmented, and changing that will require thorough review and * testing. Since OpenVPN is not susceptible to BEAST, we can just diff --git a/src/openvpn/ssl_mbedtls.h b/src/openvpn/ssl_mbedtls.h index c1c676dc..d8c366e7 100644 --- a/src/openvpn/ssl_mbedtls.h +++ b/src/openvpn/ssl_mbedtls.h @@ -105,6 +105,7 @@ struct tls_root_ctx { #endif struct external_context external_key; /**< External key context */ int *allowed_ciphers; /**< List of allowed ciphers for this connection */ + mbedtls_ecp_group_id *groups; /**< List of allowed groups for this connection */ mbedtls_x509_crt_profile cert_profile; /**< Allowed certificate types */ }; diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index 4b5ca214..8c04986c 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -557,6 +557,59 @@ tls_ctx_set_cert_profile(struct tls_root_ctx *ctx, const char *profile) #endif /* ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL */ } +void +tls_ctx_set_tls_groups(struct tls_root_ctx *ctx, const char *groups) +{ + ASSERT(ctx); + /* This method could be as easy as + * SSL_CTX_set1_groups_list(ctx->ctx, groups) + * but OpenSSL does not like the name secp256r1 for prime256v1 + * and as this is one of the more important curve to have + * the same name for OpenSSL and mbedTLS, we do this dance + */ + + int groups_count = get_num_elements(groups, ':'); + + int *glist; + /* Allocate an array for them */ + ALLOC_ARRAY_CLEAR(glist, int, groups_count); + + /* Parse allowed ciphers, getting IDs */ + int glistlen = 0; + char *tmp_groups_orig = string_alloc(groups, NULL); + char *tmp_groups = tmp_groups_orig; + + const char *token = strsep(&tmp_groups, ":"); + while (token) + { + if (streq(token, "secp256r1")) + { + token = "prime256v1"; + } + int nid = OBJ_sn2nid(token); + + if (nid == 0) + { + msg(M_WARN, "Warning unknown curve/group specified: %s", token); + } + else + { + glist[glistlen] = nid; + glistlen++; + } + token = strsep(&tmp_groups, ":"); + } + free(tmp_groups_orig); + + if (!SSL_CTX_set1_groups(ctx->ctx, glist, glistlen)) + { + crypto_msg(M_FATAL, "Failed to set allowed TLS group list: %s", + groups); + } + + free(glist); +} + void tls_ctx_check_cert_time(const struct tls_root_ctx *ctx) { @@ -577,7 +630,7 @@ tls_ctx_check_cert_time(const struct tls_root_ctx *ctx) if (cert == NULL) { - goto cleanup; /* Nothing to check if there is no certificate */ + goto cleanup; /* Nothing to check if there is no certificate */ } ret = X509_cmp_time(X509_get0_notBefore(cert), NULL); @@ -890,7 +943,7 @@ tls_ctx_add_extra_certs(struct tls_root_ctx *ctx, BIO *bio) for (;; ) { cert = NULL; - if (!PEM_read_bio_X509(bio, &cert, NULL, NULL)) /* takes ownership of cert */ + if (!PEM_read_bio_X509(bio, &cert, NULL, NULL)) /* takes ownership of cert */ { break; } @@ -1144,7 +1197,7 @@ openvpn_extkey_rsa_finish(RSA *rsa) * interface query */ const char * -get_rsa_padding_name (const int padding) +get_rsa_padding_name(const int padding) { switch (padding) { @@ -1161,14 +1214,14 @@ get_rsa_padding_name (const int padding) /** * Pass the input hash in 'dgst' to management and get the signature back. - * - * @param dgst hash to be signed - * @param dgstlen len of data in dgst - * @param sig On successful return signature is in sig. - * @param siglen length of buffer sig - * @param algorithm padding/hashing algorithm for the signature * - * @return signature length or -1 on error. + * @param dgst hash to be signed + * @param dgstlen len of data in dgst + * @param sig On successful return signature is in sig. + * @param siglen length of buffer sig + * @param algorithm padding/hashing algorithm for the signature + * + * @return signature length or -1 on error. */ static int get_sig_from_man(const unsigned char *dgst, unsigned int dgstlen, @@ -1210,7 +1263,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, return -1; } - ret = get_sig_from_man(from, flen, to, len, get_rsa_padding_name (padding)); + ret = get_sig_from_man(from, flen, to, len, get_rsa_padding_name(padding)); return (ret == len) ? ret : -1; } @@ -1266,7 +1319,7 @@ tls_ctx_use_external_rsa_key(struct tls_root_ctx *ctx, EVP_PKEY *pkey) goto err; } - RSA_free(rsa); /* doesn't necessarily free, just decrements refcount */ + RSA_free(rsa); /* doesn't necessarily free, just decrements refcount */ return 1; err: @@ -1285,7 +1338,7 @@ err: } #if ((OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) \ - || LIBRESSL_VERSION_NUMBER > 0x2090000fL) \ + || LIBRESSL_VERSION_NUMBER > 0x2090000fL) \ && !defined(OPENSSL_NO_EC) /* called when EC_KEY is destroyed */ @@ -1394,11 +1447,11 @@ tls_ctx_use_external_ec_key(struct tls_root_ctx *ctx, EVP_PKEY *pkey) if (!SSL_CTX_use_PrivateKey(ctx->ctx, privkey)) { - ec = NULL; /* avoid double freeing it below */ + ec = NULL; /* avoid double freeing it below */ goto err; } - EVP_PKEY_free(privkey); /* this will down ref privkey and ec */ + EVP_PKEY_free(privkey); /* this will down ref privkey and ec */ return 1; err: @@ -1436,7 +1489,7 @@ tls_ctx_use_management_external_key(struct tls_root_ctx *ctx) /* get the public key */ EVP_PKEY *pkey = X509_get0_pubkey(cert); - ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */ + ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */ if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { @@ -1446,7 +1499,7 @@ tls_ctx_use_management_external_key(struct tls_root_ctx *ctx) } } #if ((OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) \ - || LIBRESSL_VERSION_NUMBER > 0x2090000fL) \ + || LIBRESSL_VERSION_NUMBER > 0x2090000fL) \ && !defined(OPENSSL_NO_EC) else if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { @@ -1690,7 +1743,7 @@ tls_ctx_load_extra_certs(struct tls_root_ctx *ctx, const char *extra_certs_file, static FILE *biofp; /* GLOBAL */ static bool biofp_toggle; /* GLOBAL */ static time_t biofp_last_open; /* GLOBAL */ -static const int biofp_reopen_interval = 600; /* GLOBAL */ +static const int biofp_reopen_interval = 600; /* GLOBAL */ static void close_biofp(void) @@ -1806,9 +1859,9 @@ bio_write(BIO *bio, const uint8_t *data, int size, const char *desc) static void bio_write_post(const int status, struct buffer *buf) { - if (status == 1) /* success status return from bio_write? */ + if (status == 1) /* success status return from bio_write? */ { - memset(BPTR(buf), 0, BLEN(buf)); /* erase data just written */ + memset(BPTR(buf), 0, BLEN(buf)); /* erase data just written */ buf->len = 0; } } @@ -2106,8 +2159,8 @@ show_available_tls_ciphers_list(const char *cipher_list, crypto_msg(M_FATAL, "Cannot create SSL object"); } -#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) || \ - (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER <= 0x2090000fL) +#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) \ + || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER <= 0x2090000fL) STACK_OF(SSL_CIPHER) *sk = SSL_get_ciphers(ssl); #else STACK_OF(SSL_CIPHER) *sk = SSL_get1_supported_ciphers(ssl); @@ -2159,7 +2212,9 @@ show_available_curves(void) ALLOC_ARRAY(curves, EC_builtin_curve, crv_len); if (EC_get_builtin_curves(curves, crv_len)) { - printf("Available Elliptic curves:\n"); + printf("Consider using openssl ecparam -list_curves as\n" + "alternative to running this command to this command."); + printf("\nAvailable Elliptic curves/groups:\n"); for (n = 0; n < crv_len; n++) { const char *sname;