From patchwork Wed Oct 31 05:52:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arne Schwabe X-Patchwork-Id: 585 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director7.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id oOdMFw7e2VttYAAAIUCqbw for ; Wed, 31 Oct 2018 12:53:34 -0400 Received: from proxy12.mail.ord1d.rsapps.net ([172.30.191.6]) by director7.mail.ord1d.rsapps.net with LMTP id YAUuFw7e2VucBAAAovjBpQ ; Wed, 31 Oct 2018 12:53:34 -0400 Received: from smtp14.gate.ord1c ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy12.mail.ord1d.rsapps.net with LMTP id eJPsFg7e2VugAwAA7PHxkg ; Wed, 31 Oct 2018 12:53:34 -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: smtp14.gate.ord1c.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: 80067ab4-dd2d-11e8-ad11-bc305bf032e0-1-1 Received: from [216.105.38.7] ([216.105.38.7:54062] helo=lists.sourceforge.net) by smtp14.gate.ord1c.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id D3/C4-11097-C0ED9DB5; Wed, 31 Oct 2018 12:53:33 -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 1gHtjW-0006US-Nl; Wed, 31 Oct 2018 16:52:42 +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 1gHtjV-0006UD-5K for openvpn-devel@lists.sourceforge.NET; Wed, 31 Oct 2018 16:52:41 +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=xdmwfdFKCcjyA9N2csdUOOww7Pa9pIAo4oaXPZXE9fI=; b=ep5c+QUdPlUxbZ1aOw3NMG7e9n sEGjlIkvkmGpb4J0SIbGirqKTpPuvfP35fZw2L4Ck/0Bu83c8qsrZt06BdyZ64zNJ2eSlXDi4Tkw4 3YhkMPW9aFH4LxoTWy3EJDHF6VBQ3MaNZahMx9FlyE0KZAHzQQ74+Kstyy08RdCDmsOU=; 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=xdmwfdFKCcjyA9N2csdUOOww7Pa9pIAo4oaXPZXE9fI=; b=GjJFlcSG12xiYNxv0YVskl+Hbi fTtHXeg2UiyFCgQ6oNQptlfdIjCCFqB1OYfCr6wM8cN4XPWJipGHj+bi3qPoQIOoIOH20o8TF2L7W H+yaIbgeIEK4ggm29ryeZ8xhNXoqPyHoe2qEN7bIPmxhRSfYERE0V3EG387DCXqlCVXc=; Received: from mail.blinkt.de ([192.26.174.232]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) id 1gHtjT-003tJY-JT for openvpn-devel@lists.sourceforge.NET; Wed, 31 Oct 2018 16:52:41 +0000 Received: from kamera.blinkt.de ([2001:638:502:390:20c:29ff:fec8:535c]) by mail.blinkt.de with smtp (Exim 4.91 (FreeBSD)) (envelope-from ) id 1gHtjD-0005Vx-3X for openvpn-devel@lists.sourceforge.net; Wed, 31 Oct 2018 17:52:23 +0100 Received: (nullmailer pid 6042 invoked by uid 10006); Wed, 31 Oct 2018 16:52:22 -0000 From: Arne Schwabe To: openvpn-devel@lists.sourceforge.net Date: Wed, 31 Oct 2018 17:52:21 +0100 Message-Id: <20181031165222.5997-1-arne@rfc2549.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181007215837.489-1-arne@rfc2549.org> References: <20181007215837.489-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 X-Headers-End: 1gHtjT-003tJY-JT Subject: [Openvpn-devel] [PATCH v2 1/2] Make tls_version_max return the actual maximum version 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 Before OpenSSL 1.1.1 there could be no mismatch between compiled and actual OpenSSL version. With OpenSSL 1.1.1 we need runtime detection to detect the actual best TLS version supported. Allowing this runtime detection also allows removing some of the TLS 1.3/OpenSSL 1.1.1 #ifdefs Without this patch tls-min-version 1.3 or-highest will actually downgrade to TLS 1.3 in the "compiled with 1.1.0 and linked against 1.1.1" scenario. Signed-off-by: Arne Schwabe --- src/openvpn/ssl.c | 11 +++++------ src/openvpn/ssl_openssl.c | 33 ++++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index c0bc7a47..2a92f2e6 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -4182,12 +4182,11 @@ show_available_tls_ciphers(const char *cipher_list, { printf("Available TLS Ciphers, listed in order of preference:\n"); -#if (ENABLE_CRYPTO_OPENSSL && OPENSSL_VERSION_NUMBER >= 0x1010100fL) - printf("\nFor TLS 1.3 and newer (--tls-ciphersuites):\n\n"); - show_available_tls_ciphers_list(cipher_list_tls13, tls_cert_profile, true); -#else - (void) cipher_list_tls13; /* Avoid unused warning */ -#endif + if (tls_version_max() >= TLS_VER_1_3) + { + printf("\nFor TLS 1.3 and newer (--tls-ciphersuites):\n\n"); + show_available_tls_ciphers_list(cipher_list_tls13, tls_cert_profile, true); + } printf("\nFor TLS 1.2 and older (--tls-cipher):\n\n"); show_available_tls_ciphers_list(cipher_list, tls_cert_profile, false); diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index b5da7e13..c2c8fdc0 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -210,7 +210,23 @@ int tls_version_max(void) { #if defined(TLS1_3_VERSION) + /* If this is defined we can safely assume TLS 1.3 support */ return TLS_VER_1_3; +#elif OPENSSL_VERSION_NUMBER >= 0x10100000L + /* + * The library we are *linked* against is OpenSSL 1.1.1 + * and therefore supports TLS 1.3. This needs to be checked at runtime + * since we can be compiled against 1.1.0 and then the library can be + * upgraded to 1.1.1 + */ + if (OpenSSL_version_num() >= 0x1010100fL) + { + return TLS_VER_1_3; + } + else + { + return TLS_VER_1_2; + } #elif defined(TLS1_2_VERSION) || defined(SSL_OP_NO_TLSv1_2) return TLS_VER_1_2; #elif defined(TLS1_1_VERSION) || defined(SSL_OP_NO_TLSv1_1) @@ -236,12 +252,20 @@ openssl_tls_version(int ver) { return TLS1_2_VERSION; } -#if defined(TLS1_3_VERSION) else if (ver == TLS_VER_1_3) { + /* + * Supporting the library upgraded to TLS1.3 without recompile + * is enough to support here with a simple constant that the same + * as in the TLS 1.3, so spec it is very unlikely that OpenSSL + * will change this constant + */ +#ifndef TLS1_3_VERSION + return 0x0304; +#else return TLS1_3_VERSION; - } #endif + } return 0; } @@ -1948,14 +1972,13 @@ show_available_tls_ciphers_list(const char *cipher_list, crypto_msg(M_FATAL, "Cannot create SSL_CTX object"); } -#if (OPENSSL_VERSION_NUMBER >= 0x1010100fL) if (tls13) { - SSL_CTX_set_min_proto_version(tls_ctx.ctx, TLS1_3_VERSION); + SSL_CTX_set_min_proto_version(tls_ctx.ctx, + openssl_tls_version(TLS_VER_1_3)); tls_ctx_restrict_ciphers_tls13(&tls_ctx, cipher_list); } else -#endif { SSL_CTX_set_max_proto_version(tls_ctx.ctx, TLS1_2_VERSION); tls_ctx_restrict_ciphers(&tls_ctx, cipher_list); From patchwork Wed Oct 31 05:52:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arne Schwabe X-Patchwork-Id: 586 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director8.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id 8HtuORDe2VtdTgAAIUCqbw for ; Wed, 31 Oct 2018 12:53:36 -0400 Received: from proxy11.mail.ord1d.rsapps.net ([172.30.191.6]) by director8.mail.ord1d.rsapps.net with LMTP id 8D4QORDe2VuzdQAAfY0hYg ; Wed, 31 Oct 2018 12:53:36 -0400 Received: from smtp14.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy11.mail.ord1d.rsapps.net with LMTP id +NgEORDe2VtxXAAAgKDEHA ; Wed, 31 Oct 2018 12:53:36 -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: smtp14.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: 817a5474-dd2d-11e8-9927-525400504bae-1-1 Received: from [216.105.38.7] ([216.105.38.7:45093] helo=lists.sourceforge.net) by smtp14.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id E1/40-19441-F0ED9DB5; Wed, 31 Oct 2018 12:53:35 -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 1gHtjP-0001bq-Nw; Wed, 31 Oct 2018 16:52:35 +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 1gHtjO-0001bh-5T for openvpn-devel@lists.sourceforge.NET; Wed, 31 Oct 2018 16:52:34 +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=d/PabuDBgzMimIhLDud/UwQrPgBHaTh1jq1r6hb/3f0=; b=YPBsvR46m4XXh5pHQFXDNvmRxK u5faC40kdzDGrHCXIW5X6W9rBePJPmhtAHaXfXPjIuJdshglIRsILfbMurszaATxAL/voGX7J/xUa sprmdPEbs/U6As42t7ypu+e1V9RDla1xn67xceQIwtKH8x728eW/VQk95pmNziCcRm84=; 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=d/PabuDBgzMimIhLDud/UwQrPgBHaTh1jq1r6hb/3f0=; b=cBGUkF3Tc+l1z2prXNmiY2QLu8 LkAvxo9sMMFyQQ4z77aX+77GXBJD7QKmXR+AUtI5k+9Qza882ZyEAWYhYjDnuRN6GRinu5HKBswmm Gsqs3ZxCfeye6GWayPhTy6txiOYmtN23XxROjR6cUMVbfcLKYAtvHCpb5OW6Z79F0jAQ=; Received: from mail.blinkt.de ([192.26.174.232]) by sfi-mx-4.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) id 1gHtjK-00Ft38-21 for openvpn-devel@lists.sourceforge.NET; Wed, 31 Oct 2018 16:52:34 +0000 Received: from kamera.blinkt.de ([2001:638:502:390:20c:29ff:fec8:535c]) by mail.blinkt.de with smtp (Exim 4.91 (FreeBSD)) (envelope-from ) id 1gHtjD-0005W0-5a for openvpn-devel@lists.sourceforge.net; Wed, 31 Oct 2018 17:52:23 +0100 Received: (nullmailer pid 6045 invoked by uid 10006); Wed, 31 Oct 2018 16:52:23 -0000 From: Arne Schwabe To: openvpn-devel@lists.sourceforge.net Date: Wed, 31 Oct 2018 17:52:22 +0100 Message-Id: <20181031165222.5997-2-arne@rfc2549.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181031165222.5997-1-arne@rfc2549.org> References: <20181031165222.5997-1-arne@rfc2549.org> In-Reply-To: <20181007215837.489-1-arne@rfc2549.org> References: <20181007215837.489-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 X-Headers-End: 1gHtjK-00Ft38-21 Subject: [Openvpn-devel] [PATCH v2 2/2] Add support for OpenSSL TLS 1.3 when using management-external-key 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 For TLS 1.0 to 1.2 and OpenSSL 1.1.0 calls us and requires a PKCS1 padded response. As TLS 1.3 mandates RSA-PSS padding support and also requires an TLS 1.3 implementation to support RSA-PSS for older TLS version, OpenSSL will query us to sign an already RSA-PSS padded string. This patch adds an 'unpadded' and 'pkcs1' parameter to the management-external-key option to signal that the client is able to support pkcs1 as well as unpadded signature requests. Since clients that implement the management-external-key interface are usually rather tightly integrated solutions (OpenVPN Connect in the past, OpenVPN for Android), it is reasonable to expect that upgrading the OpenSSL library can be done together with management interface changes. Therefore we provide no backwards compatbility for mangement-interface clients not supporting OpenSSL 1.1.1. Using the management api client version instead might seem like the more logical way but since we only now that version very late, it would extra logic and complexity to deal with this asynchronous behaviour. Instead just give an error early if OpenSSL 1.1.1 and management-external-key without nopadding is detected. The interface is prepared for signalling PCKS1 and RSA-PSS support instead of signalling unpadded support. Patch v3: fix overlong lines and few other style patches. Note two overlong lines concerning mbedtls are not fixed as they are removed/shortend by the mbed tls patch to avoid conflicts Patch v4: Setting minimum TLS version proved to be not enough and instead of implementing a whole compability layer we require mangement-clients to implement the new feature when they want to use OpenSSL 1.1.1 Add a padding=ALGORITHM argument to pk-sig to indicate the algorithm. Drop adding PKCS1 ourselves. Signed-off-by: Arne Schwabe --- doc/management-notes.txt | 13 ++++++++++- doc/openvpn.8 | 7 ++++-- src/openvpn/manage.c | 18 +++++++++++--- src/openvpn/manage.h | 26 ++++++++++++++------- src/openvpn/options.c | 45 ++++++++++++++++++++++++++++++++--- src/openvpn/ssl_mbedtls.c | 7 ++++-- src/openvpn/ssl_openssl.c | 49 +++++++++++++++++++++++++++++++-------- 7 files changed, 136 insertions(+), 29 deletions(-) diff --git a/doc/management-notes.txt b/doc/management-notes.txt index 17645c1d..f685af28 100644 --- a/doc/management-notes.txt +++ b/doc/management-notes.txt @@ -816,6 +816,7 @@ actual private key. When the SSL protocol needs to perform a sign operation, the data to be signed will be sent to the management interface via a notification as follows: +>PK_SIGN:[BASE64_DATA],[ALG] (if client announces support for management version > 2) >PK_SIGN:[BASE64_DATA] (if client announces support for management version > 1) >RSA_SIGN:[BASE64_DATA] (only older clients will be prompted like this) @@ -823,7 +824,7 @@ The management interface client should then create an appropriate signature of the (decoded) BASE64_DATA using the private key and return the SSL signature as follows: -pk-sig (or rsa-sig) +pk-sig (or rsa-sig) [BASE64_SIG_LINE] . . @@ -833,6 +834,12 @@ END Base 64 encoded output of RSA_private_encrypt for RSA or ECDSA_sign() for EC using OpenSSL or mbedtls_pk_sign() using mbed TLS will provide a correct signature. +The rsa-sig interfaces expects PKCS1 padded signatures for RSA keys +(RSA_PKCS1_PADDING). EC signatures are always unpadded. + +The padding field is only present when pk-sig is used and +currently the following values can be requested PCKS1 and NOPADDING for RSA +certificates and NOPADDING for EC certificates. This capability is intended to allow the use of arbitrary cryptographic service providers with OpenVPN via the management interface. @@ -840,6 +847,10 @@ service providers with OpenVPN via the management interface. New and updated clients are expected to use the version command to announce a version > 1 and handle '>PK_SIGN' prompt and respond with 'pk-sig'. +The older rsa-sig and pk-sig interfaces hav no capability to indidicate the +requested padding algorithm. When the 'nopadding' using version >= 2 is required. +To support TLS 1.3 with OpenSSL 1.1.1 supporting unpadded signatures is required. + COMMAND -- certificate (OpenVPN 2.4 or higher) ---------------------------------------------- Provides support for external storage of the certificate. Requires the diff --git a/doc/openvpn.8 b/doc/openvpn.8 index e80d4696..3cd5d944 100644 --- a/doc/openvpn.8 +++ b/doc/openvpn.8 @@ -2739,10 +2739,13 @@ Allow management interface to override directives (client\-only). .\"********************************************************* .TP -.B \-\-management\-external\-key +.B \-\-management\-external\-key [nopadding] [pkcs1] Allows usage for external private key file instead of .B \-\-key -option (client\-only). +option (client\-only). The optional parameters nopadding and +pkcs1 signal support for different padding algorithms. See +doc/mangement-notes.txt for a complete description of this +feature. .\"********************************************************* .TP .B \-\-management\-external\-cert certificate\-hint diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c index 8b633f20..62d4bc7b 100644 --- a/src/openvpn/manage.c +++ b/src/openvpn/manage.c @@ -3639,18 +3639,30 @@ management_query_multiline_flatten(struct management *man, char * /* returns allocated base64 signature */ -management_query_pk_sig(struct management *man, - const char *b64_data) +management_query_pk_sig(struct management *man, const char *b64_data, + const char *padding) { const char *prompt = "PK_SIGN"; const char *desc = "pk-sign"; + struct buffer buf_data = alloc_buf(strlen(b64_data) + strlen(padding) + 20); + if (man->connection.client_version <= 1) { prompt = "RSA_SIGN"; desc = "rsa-sign"; } - return management_query_multiline_flatten(man, b64_data, prompt, desc, + + buf_write(&buf_data, b64_data, (int) strlen(b64_data)); + if (man->connection.client_version > 2) + { + buf_write(&buf_data, ",", (int) strlen(",")); + buf_write(&buf_data, padding, (int) strlen(padding)); + } + char* ret = management_query_multiline_flatten(man, + (char *)buf_bptr(&buf_data), prompt, desc, &man->connection.ext_key_state, &man->connection.ext_key_input); + free_buf(&buf_data); + return ret; } char * diff --git a/src/openvpn/manage.h b/src/openvpn/manage.h index d24abe09..5c35a5ca 100644 --- a/src/openvpn/manage.h +++ b/src/openvpn/manage.h @@ -31,7 +31,7 @@ #include "socket.h" #include "mroute.h" -#define MANAGEMENT_VERSION 2 +#define MANAGEMENT_VERSION 3 #define MANAGEMENT_N_PASSWORD_RETRIES 3 #define MANAGEMENT_LOG_HISTORY_INITIAL_SIZE 100 #define MANAGEMENT_ECHO_BUFFER_SIZE 100 @@ -341,12 +341,18 @@ struct management *management_init(void); #ifdef MANAGEMENT_PF #define MF_CLIENT_PF (1<<7) #endif -#define MF_UNIX_SOCK (1<<8) -#define MF_EXTERNAL_KEY (1<<9) -#define MF_UP_DOWN (1<<10) -#define MF_QUERY_REMOTE (1<<11) -#define MF_QUERY_PROXY (1<<12) -#define MF_EXTERNAL_CERT (1<<13) +#define MF_UNIX_SOCK (1<<8) +#define MF_EXTERNAL_KEY (1<<9) +#define MF_EXTERNAL_KEY_NOPADDING (1<<10) +#define MF_EXTERNAL_KEY_PKCS1PAD (1<<11) +#define MF_UP_DOWN (1<<12) +#define MF_QUERY_REMOTE (1<<13) +#define MF_QUERY_PROXY (1<<14) +#define MF_EXTERNAL_CERT (1<<15) + +#define MF_RSA_PKCS1_PADDING 1 +#define MF_RSA_NO_PADDING 2 + bool management_open(struct management *man, const char *addr, @@ -430,7 +436,11 @@ void management_learn_addr(struct management *management, #endif -char *management_query_pk_sig(struct management *man, const char *b64_data); +#define PKSIG_PKCS1 1 +#define PK + +char *management_query_pk_sig(struct management *man, const char *b64_data, + const char* pading); char *management_query_cert(struct management *man, const char *cert_name); diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 406669a3..229d6ce3 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -2141,6 +2141,22 @@ options_postprocess_verify_ce(const struct options *options, const struct connec #endif +#if defined(ENABLE_CRYPTOAPI) + if (o->cryptoapi_cert && (tls_version_max() >= TLS_VER_1_3)) + { + msg(M_ERR, "Cryptoapi support currently is incompatible " + "with OpenSSL 1.1.1/TLS 1.3"); + } +#endif +#if defined(ENABLE_MANAGEMENT) + if ((options->management_flags & MF_EXTERNAL_KEY) && + !(options->management_flags & (MF_EXTERNAL_KEY_NOPADDING)) + ) + { + msg(M_ERR, "management-external-key with OpenSSL 1.1.1 requires " + "the nopadding argument/support"); + } +#endif /* * Windows-specific options. */ @@ -3068,7 +3084,6 @@ options_postprocess_mutate(struct options *o) options_postprocess_http_proxy_override(o); } #endif - #if P2MP /* * Save certain parms before modifying options via --pull @@ -5151,9 +5166,33 @@ add_option(struct options *options, options->management_write_peer_info_file = p[1]; } #ifdef ENABLE_MANAGEMENT - else if (streq(p[0], "management-external-key") && !p[1]) + else if (streq(p[0], "management-external-key")) { VERIFY_PERMISSION(OPT_P_GENERAL); + for (int j = 1; j < MAX_PARMS && p[j] != NULL; ++j) + { + if (streq(p[j], "nopadding")) + { + options->management_flags |= MF_EXTERNAL_KEY_NOPADDING; + } + else if (p[1] && streq(p[1], "pkcs1")) + { + options->management_flags |= MF_EXTERNAL_KEY_PKCS1PAD; + } + else + { + msg(msglevel, "Unknown management-external-key flag: %s" , p[j]); + } + } + /* + * When no option is present, assume that only PKCS1 + * padding is supported + */ + if (! (options->management_flags & + (MF_EXTERNAL_KEY_NOPADDING | MF_EXTERNAL_KEY_PKCS1PAD))) + { + options->management_flags |= MF_EXTERNAL_KEY_PKCS1PAD; + } options->management_flags |= MF_EXTERNAL_KEY; } else if (streq(p[0], "management-external-cert") && p[1] && !p[2]) @@ -8456,4 +8495,4 @@ add_option(struct options *options, } err: gc_free(&gc); -} \ No newline at end of file +} diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c index f7e8c2d0..09b1a8fa 100644 --- a/src/openvpn/ssl_mbedtls.c +++ b/src/openvpn/ssl_mbedtls.c @@ -626,7 +626,6 @@ tls_ctx_use_external_signing_func(struct tls_root_ctx *ctx, } #ifdef ENABLE_MANAGEMENT - /** Query the management interface for a signature, see external_sign_func. */ static bool management_sign_func(void *sign_ctx, const void *src, size_t src_len, @@ -641,7 +640,11 @@ management_sign_func(void *sign_ctx, const void *src, size_t src_len, goto cleanup; } - if (!(dst_b64 = management_query_pk_sig(management, src_b64))) + /* + * We only use PKCS1 signatures at the moment in mbed TLS, + * there the signature parameter is hardcoded + */ + if (!(dst_b64 = management_query_pk_sig(management, src_b64, "PKCS1"))) { goto cleanup; } diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index c2c8fdc0..237c2b55 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -1079,24 +1079,46 @@ openvpn_extkey_rsa_finish(RSA *rsa) return 1; } -/* Pass the input hash in 'dgst' to management and get the signature back. +/* + * Convert OpenSSL's constant to the strings used in the management + * interface query + */ +const char* +get_sig_padding_name(const int padding) +{ + switch(padding) + { + case RSA_PKCS1_PADDING: + return "PKCS1"; + case RSA_NO_PADDING: + return "NOPADDING"; + default: + return "UNKNOWN"; + } +} + +/* + * Pass the input hash in 'dgst' to management and get the signature back. * On input siglen contains the capacity of the buffer 'sig'. * On return signature is in sig. + * pkcs1 controls if pkcs1 padding is required * Return value is signature length or -1 on error. */ static int get_sig_from_man(const unsigned char *dgst, unsigned int dgstlen, - unsigned char *sig, unsigned int siglen) + unsigned char *sig, unsigned int siglen, + int padding) { char *in_b64 = NULL; char *out_b64 = NULL; int len = -1; - /* convert 'dgst' to base64 */ - if (management - && openvpn_base64_encode(dgst, dgstlen, &in_b64) > 0) + int bencret = openvpn_base64_encode(dgst, dgstlen, &in_b64); + + if (management && bencret > 0) { - out_b64 = management_query_pk_sig(management, in_b64); + out_b64 = management_query_pk_sig(management, in_b64, + get_sig_padding_name(padding)); } if (out_b64) { @@ -1110,18 +1132,19 @@ get_sig_from_man(const unsigned char *dgst, unsigned int dgstlen, /* sign arbitrary data */ static int -rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, + int padding) { unsigned int len = RSA_size(rsa); int ret = -1; - if (padding != RSA_PKCS1_PADDING) + if (padding != RSA_PKCS1_PADDING && padding != RSA_NO_PADDING) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); return -1; } - ret = get_sig_from_man(from, flen, to, len); + ret = get_sig_from_man(from, flen, to, len, padding); return (ret == len)? ret : -1; } @@ -1215,7 +1238,13 @@ ecdsa_sign(int type, const unsigned char *dgst, int dgstlen, unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *ec) { int capacity = ECDSA_size(ec); - int len = get_sig_from_man(dgst, dgstlen, sig, capacity); + /* + * ECDSA does not seem to have proper constants for paddings since + * there are only signatures without padding at the moment, reuse + * RSA_NO_PADDING for now as it will trigger querying for "NOPADDING" in the + * management interface + */ + int len = get_sig_from_man(dgst, dgstlen, sig, capacity, RSA_NO_PADDING); if (len > 0) {