From patchwork Sun Nov 12 05:36:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steffan Karger X-Patchwork-Id: 77 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director5.mail.ord1d.rsapps.net ([172.27.255.57]) by backend31.mail.ord1d.rsapps.net (Dovecot) with LMTP id 83SKOCJ5CFrfEQAAgoeIoA for ; Sun, 12 Nov 2017 11:38:59 -0500 Received: from proxy14.mail.iad3a.rsapps.net ([172.27.255.57]) by director5.mail.ord1d.rsapps.net (Dovecot) with LMTP id 63YjMiJ5CFrdHgAAsdCWiw ; Sun, 12 Nov 2017 11:38:58 -0500 Received: from smtp32.gate.iad3a ([172.27.255.57]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy14.mail.iad3a.rsapps.net (Dovecot) with LMTP id 6iJDLyJ5CFqQFwAA1+b4IQ ; Sun, 12 Nov 2017 11:38:58 -0500 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.34.181.88] Authentication-Results: smtp32.gate.iad3a.rsapps.net; iprev=pass policy.iprev="216.34.181.88"; 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; dkim=fail (signature verification failed) header.d=karger-me.20150623.gappssmtp.com; dmarc=none (p=nil; dis=none) header.from=karger.me X-Classification-ID: faebfe38-c7c7-11e7-87fe-bc305bf65d38-1-1 Received: from [216.34.181.88] ([216.34.181.88:30803] helo=lists.sourceforge.net) by smtp32.gate.iad3a.rsapps.net (envelope-from ) (ecelerity 4.2.1.56364 r(Core:4.2.1.14)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 84/42-05723-229780A5; Sun, 12 Nov 2017 11:38:58 -0500 Received: from localhost ([127.0.0.1] helo=sfs-ml-4.v29.ch3.sourceforge.com) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.89) (envelope-from ) id 1eDvGs-0005Np-DY; Sun, 12 Nov 2017 16:38:10 +0000 Received: from sfi-mx-2.v28.ch3.sourceforge.com ([172.29.28.192] helo=mx.sourceforge.net) by sfs-ml-4.v29.ch3.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.89) (envelope-from ) id 1eDvGq-0005Ng-OS for openvpn-devel@lists.sourceforge.net; Sun, 12 Nov 2017 16:38:08 +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:Cc: To:From:Sender:Reply-To: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=r6J/T924YSS/fvjguEhMKql0c+O7s+UEpJRa+w8YwKg=; b=JkVE0Q74PrfFOwaTSAxOP3RNAg j8QboHd+DNRAVcO3oXeYfpRW5NsS/il7ZLhbM6bZwzekdShV4LiykCu6qlurEFXlx881Bp2gM/HF4 otzkmiorWXcoWMoTVDvPRL/PkJRMNT3j49F+aOPn/6EnG1TRmI+DtMmMre73vX35C2Io=; 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:Cc:To:From:Sender:Reply-To :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=r6J/T924YSS/fvjguEhMKql0c+O7s+UEpJRa+w8YwKg=; b=GIL0CjVqrmS/nKbEiZi3Rkh3ZV r9O96ZEAWz4IK5034t+dhbW5KtrPHxHXwEmy+3hePL13I8KLUAsaNmn5KNx4HknohQJ3x6fabWnej BSs+7a2cPaGPoOAVGxm6sFh0WNBq4xMaGMT+Z0JvB+tG3jEHnyJLwQG2SXHgF6/kdCo0=; Received: from mail-wr0-f176.google.com ([209.85.128.176]) by sfi-mx-2.v28.ch3.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.89) id 1eDvGn-0000BD-LX for openvpn-devel@lists.sourceforge.net; Sun, 12 Nov 2017 16:38:08 +0000 Received: by mail-wr0-f176.google.com with SMTP id 15so12417274wrb.5 for ; Sun, 12 Nov 2017 08:38:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=karger-me.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=r6J/T924YSS/fvjguEhMKql0c+O7s+UEpJRa+w8YwKg=; b=mBThj1sVCCdesT2cTT+nIqShAMK68CWl9Vh1b5otL/XhvPhx+4nDMDDXwpWRtwZBOj ZEKys8O/qOi02fDXr46IMv4kDVjqtfJz7uA4N1ETS1SnACXZkAMWsQ0EGqFwDKIu38Qd r00tqQFBwPgZ9B28Tx40BI5lOpfzMSERqAfvZkUY65CWS2SHZsWyBipB0WqnDhyw2r74 JhE3eb6IyUCG+UZVWKrWgrMLJgyPpf/UafDr6EgbfrdgSPJ65Q2Y/pyBRVjeieOoQs6Y fZTjRc1ahVe3miumoqF7vpxQJ8eZyddyq7lcZH75QtsqiOR4Ic5/Cy+ENGLhr+Cu8CJS mvFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=r6J/T924YSS/fvjguEhMKql0c+O7s+UEpJRa+w8YwKg=; b=e9fkOLxMAZXb3DQAzp1q7C/QQ3DpdHJxMSlwpPT+Sva382Z8hE8NjkUCCj6c4GswT/ wmKVSY3B/rIzSqt4ijR8o35CvjNNrAZdocoZFdJxjTAt60dxXPaNC6Q0uC73c3W8UCgc hTBuFPHYqrPInRt85gwCNpsycrUmjuF81nOsrguZ44f1dU2LPFWsclApUQfWCYrZrBL2 KogeCyzdo8+QZSkqaEmdrF2lHzEovQ8emOvS2SUaf9NWQVeQ3qlfr+tLySIEhYhChVst ZaXFCNPBM8UkPKQLSDUQNSNOJvh04zREH/9vOgHCiHnO2ngJzv3NLXvyO5F0RvjI8GpY YSPg== X-Gm-Message-State: AJaThX6EW58pFaZyB2Swtfc3dr1Efw7un03lhMwfBa/0SenOgPpeqVGU UGC82VTnoO6xKfVmljuiWr7hTOuA2MI= X-Google-Smtp-Source: AGs4zMbgI6n+7W3NMN1fOu15Q5dlTnGtt9PpLG1hvYzaK7MK6L2Ew0dJiBvt5LIR7GlJmwcWt+lmxQ== X-Received: by 10.223.129.41 with SMTP id 38mr5514030wrm.57.1510504679103; Sun, 12 Nov 2017 08:37:59 -0800 (PST) Received: from localhost.localdomain ([46.183.103.8]) by smtp.gmail.com with ESMTPSA id y99sm9984164wmh.0.2017.11.12.08.37.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 12 Nov 2017 08:37:58 -0800 (PST) From: Steffan Karger To: openvpn-devel@lists.sourceforge.net Date: Sun, 12 Nov 2017 17:36:36 +0100 Message-Id: <20171112163636.17434-1-steffan@karger.me> X-Mailer: git-send-email 2.14.1 In-Reply-To: <5f8d8043-5725-f535-e623-da042984196b@unstable.cc> References: <5f8d8043-5725-f535-e623-da042984196b@unstable.cc> X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [209.85.128.176 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-Headers-End: 1eDvGn-0000BD-LX Subject: [Openvpn-devel] [PATCH v6] Add --tls-cert-profile option for mbedtls builds 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 From: Steffan Karger This allows the user to specify what certificate crypto algorithms to support. The supported profiles are 'preferred', 'legacy' (default) and 'suiteb', as discussed in <84590a17-1c48-9df2-c48e-4160750b2e33@fox-it.com> (https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14214.html). This fully implements the feature for mbed TLS builds, because for mbed it is both more easy to implement and the most relevant because mbed TLS 2+ is by default somewhat restrictive by requiring 2048-bit+ for RSA keys. For OpenSSL, this implements an approximation based on security levels, as discussed at the hackathon in Karlsruhe. This patch uses 'legacy' as the default profile following discussion on the openvpn-devel mailing list. This way this patch can be applied to both the release/2.4 and master branches. I'll send a follow-up patch for the master branch to change the default to 'preferred' later. Signed-off-by: Steffan Karger Acked-by: Antonio Quartulli Signed-off-by: Jeremie Courreges-Anglas Signed-off-by: Jeremie Courreges-Anglas Acked-by: Steffan Karger Tested-by: Steffan Karger --- v2: - add documentation (manpage, Changes.rst and --help) - no longer print a warning message on each startup for OpenSSL builds v3: - remove format changes in unrelated items (introduced in v2) - Update Changes.rst text to reflect that the default in 2.4.2 is 'legacy' and the default in 2.5 will be 'preferred' (as discussed on the ML). - This patch is for the master branch only now (due to the default). v4: - Ignore the option for OpenSSL builds, instead of rejecting the option and refusing to start. - Patch is for master and release/2.4 again. A follow-up patch will change the default for master later on. v5: - Add (approximate) OpenSSL implementation. - Remove null check for argument that couln't be null anyway. v6: - Fix compilation with OpenSSL 1.0.x Changes.rst | 12 +++++++++++ doc/openvpn.8 | 31 ++++++++++++++++++++++++++ src/openvpn/init.c | 3 ++- src/openvpn/options.c | 10 +++++++++ src/openvpn/options.h | 1 + src/openvpn/ssl.c | 3 +++ src/openvpn/ssl_backend.h | 17 +++++++++++++-- src/openvpn/ssl_mbedtls.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++- src/openvpn/ssl_mbedtls.h | 1 + src/openvpn/ssl_openssl.c | 38 +++++++++++++++++++++++++++++++- 10 files changed, 166 insertions(+), 5 deletions(-) diff --git a/Changes.rst b/Changes.rst index db9b18b9..a6090cf5 100644 --- a/Changes.rst +++ b/Changes.rst @@ -321,6 +321,18 @@ Maintainer-visible changes i386/i686 builds on RHEL5. +Version 2.4.5 +============= + +New features +------------ +- The new option ``--tls-cert-profile`` can be used to restrict the set of + allowed crypto algorithms in TLS certificates in mbed TLS builds. The + default profile is 'legacy' for now, which allows SHA1+, RSA-1024+ and any + elliptic curve certificates. The default will be changed to the 'preferred' + profile in the future, which requires SHA2+, RSA-2048+ and any curve. + + Version 2.4.3 ============= diff --git a/doc/openvpn.8 b/doc/openvpn.8 index a4189ac2..549d96cb 100644 --- a/doc/openvpn.8 +++ b/doc/openvpn.8 @@ -4917,6 +4917,37 @@ when using mbed TLS or OpenSSL. .\"********************************************************* .TP +.B \-\-tls\-cert\-profile profile +Set the allowed cryptographic algorithms for certificates according to +.B profile\fN. + +The following profiles are supported: + +.B legacy +(default): SHA1 and newer, RSA 2048-bit+, any elliptic curve. + +.B preferred +: SHA2 and newer, RSA 2048-bit+, any elliptic curve. + +.B suiteb +: SHA256/SHA384, ECDSA with P-256 or P-384. + +This option is only fully supported for mbed TLS builds. OpenSSL builds use +the following approximation: + +.B legacy +(default): sets "security level 1" + +.B preferred +: sets "security level 2" + +.B suiteb +: sets "security level 3" and \-\-tls\-cipher "SUITEB128". + +OpenVPN will migrate to 'preferred' as default in the future. Please ensure +that your keys already comply. +.\"********************************************************* +.TP .B \-\-tls\-timeout n Packet retransmit timeout on TLS control channel if no acknowledgment from remote within diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 1ed2c55e..cccc63b2 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1016,7 +1016,8 @@ print_openssl_info(const struct options *options) } if (options->show_tls_ciphers) { - show_available_tls_ciphers(options->cipher_list); + show_available_tls_ciphers(options->cipher_list, + options->tls_cert_profile); } if (options->show_curves) { diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 49ed004b..9d6e279a 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -599,6 +599,8 @@ static const char usage_message[] = #endif "--tls-cipher l : A list l of allowable TLS ciphers separated by : (optional).\n" " : Use --show-tls to see a list of supported TLS ciphers.\n" + "--tls-cert-profile p : Set the allowed certificate crypto algorithm profile\n" + " (default=legacy).\n" "--tls-timeout n : Packet retransmit timeout on TLS control channel\n" " if no ACK from remote within n seconds (default=%d).\n" "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and recvd.\n" @@ -872,6 +874,7 @@ init_options(struct options *o, const bool init_gc) o->renegotiate_seconds = 3600; o->handshake_window = 60; o->transition_window = 3600; + o->tls_cert_profile = NULL; o->ecdh_curve = NULL; #ifdef ENABLE_X509ALTUSERNAME o->x509_username_field = X509_USERNAME_FIELD_DEFAULT; @@ -1750,6 +1753,7 @@ show_settings(const struct options *o) SHOW_STR(cryptoapi_cert); #endif SHOW_STR(cipher_list); + SHOW_STR(tls_cert_profile); SHOW_STR(tls_verify); SHOW_STR(tls_export_cert); SHOW_INT(verify_x509_type); @@ -2729,6 +2733,7 @@ options_postprocess_verify_ce(const struct options *options, const struct connec MUST_BE_UNDEF(pkcs12_file); #endif MUST_BE_UNDEF(cipher_list); + MUST_BE_UNDEF(tls_cert_profile); MUST_BE_UNDEF(tls_verify); MUST_BE_UNDEF(tls_export_cert); MUST_BE_UNDEF(verify_x509_name); @@ -7831,6 +7836,11 @@ add_option(struct options *options, VERIFY_PERMISSION(OPT_P_GENERAL); options->cipher_list = p[1]; } + else if (streq(p[0], "tls-cert-profile") && p[1] && !p[2]) + { + VERIFY_PERMISSION(OPT_P_GENERAL); + options->tls_cert_profile = 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 496c1143..85ff200b 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -502,6 +502,7 @@ struct options const char *priv_key_file; const char *pkcs12_file; const char *cipher_list; + const char *tls_cert_profile; const char *ecdh_curve; const char *tls_verify; int verify_x509_type; diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index cb94229a..359ef635 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -616,6 +616,9 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx) tls_ctx_client_new(new_ctx); } + /* Restrict allowed certificate crypto algorithms */ + tls_ctx_set_cert_profile(new_ctx, options->tls_cert_profile); + /* Allowable ciphers */ /* Since @SECLEVEL also influces loading of certificates, set the * cipher restrictions before loading certificates */ diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h index aba5a4de..f588110c 100644 --- a/src/openvpn/ssl_backend.h +++ b/src/openvpn/ssl_backend.h @@ -176,6 +176,16 @@ void tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags); */ void tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers); +/** + * Set the TLS certificate profile. The profile defines which crypto + * algorithms may be used in the supplied certificate. + * + * @param ctx TLS context to restrict, must be valid. + * @param profile The profile name ('preferred', 'legacy' or 'suiteb'). + * Defaults to 'preferred' if NULL. + */ +void tls_ctx_set_cert_profile(struct tls_root_ctx *ctx, const char *profile); + /** * 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, @@ -505,9 +515,12 @@ void print_details(struct key_state_ssl *ks_ssl, const char *prefix); * Show the TLS ciphers that are available for us to use in the OpenSSL * library. * - * @param - list of allowed TLS cipher, or NULL. + * @param cipher_list list of allowed TLS cipher, or NULL. + * @param tls_cert_profile TLS certificate crypto profile name. */ -void show_available_tls_ciphers(const char *tls_ciphers); +void +show_available_tls_ciphers(const char *cipher_list, + const char *tls_cert_profile); /* * Show the available elliptic curves in the crypto library diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c index 861d936d..09829ebb 100644 --- a/src/openvpn/ssl_mbedtls.c +++ b/src/openvpn/ssl_mbedtls.c @@ -62,6 +62,34 @@ #include #include +static const mbedtls_x509_crt_profile openvpn_x509_crt_profile_legacy = +{ + /* Hashes from SHA-1 and above */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), + 0xFFFFFFF, /* Any PK alg */ + 0xFFFFFFF, /* Any curve */ + 1024, /* RSA-1024 and larger */ +}; + +static const mbedtls_x509_crt_profile openvpn_x509_crt_profile_preferred = +{ + /* SHA-2 and above */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), + 0xFFFFFFF, /* Any PK alg */ + 0xFFFFFFF, /* Any curve */ + 2048, /* RSA-2048 and larger */ +}; + +#define openvpn_x509_crt_profile_suiteb mbedtls_x509_crt_profile_suiteb; + void tls_init_lib(void) { @@ -250,6 +278,27 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) free(tmp_ciphers_orig); } +void +tls_ctx_set_cert_profile(struct tls_root_ctx *ctx, const char *profile) +{ + if (!profile || 0 == strcmp(profile, "legacy")) + { + ctx->cert_profile = openvpn_x509_crt_profile_legacy; + } + else if (0 == strcmp(profile, "preferred")) + { + ctx->cert_profile = openvpn_x509_crt_profile_preferred; + } + else if (0 == strcmp(profile, "suiteb")) + { + ctx->cert_profile = openvpn_x509_crt_profile_suiteb; + } + else + { + msg (M_FATAL, "ERROR: Invalid cert profile: %s", profile); + } +} + void tls_ctx_check_cert_time(const struct tls_root_ctx *ctx) { @@ -917,6 +966,8 @@ key_state_ssl_init(struct key_state_ssl *ks_ssl, mbedtls_ssl_conf_rng(&ks_ssl->ssl_config, mbedtls_ctr_drbg_random, rand_ctx_get()); + mbedtls_ssl_conf_cert_profile(&ks_ssl->ssl_config, &ssl_ctx->cert_profile); + if (ssl_ctx->allowed_ciphers) { mbedtls_ssl_conf_ciphersuites(&ks_ssl->ssl_config, ssl_ctx->allowed_ciphers); @@ -1271,12 +1322,14 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) } void -show_available_tls_ciphers(const char *cipher_list) +show_available_tls_ciphers(const char *cipher_list, + const char *tls_cert_profile) { struct tls_root_ctx tls_ctx; const int *ciphers = mbedtls_ssl_list_ciphersuites(); tls_ctx_server_new(&tls_ctx); + tls_ctx_set_cert_profile(&tls_ctx, tls_cert_profile); tls_ctx_restrict_ciphers(&tls_ctx, cipher_list); if (tls_ctx.allowed_ciphers) diff --git a/src/openvpn/ssl_mbedtls.h b/src/openvpn/ssl_mbedtls.h index f69b6100..341da7d4 100644 --- a/src/openvpn/ssl_mbedtls.h +++ b/src/openvpn/ssl_mbedtls.h @@ -82,6 +82,7 @@ struct tls_root_ctx { struct external_context *external_key; /**< Management external key */ #endif int *allowed_ciphers; /**< List of allowed ciphers for this connection */ + mbedtls_x509_crt_profile cert_profile; /**< Allowed certificate types */ }; struct key_state_ssl { diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index 0bfb6939..de89cb13 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -383,6 +383,40 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) } } +void +tls_ctx_set_cert_profile(struct tls_root_ctx *ctx, const char *profile) +{ +#if (OPENSSL_VERSION_NUMBER >= 0x10100000) + /* OpenSSL does not have certificate profiles, but a complex set of + * callbacks that we could try to implement to achieve something similar. + * For now, use OpenSSL's security levels to achieve similar (but not equal) + * behaviour. */ + if (!profile || 0 == strcmp(profile, "legacy")) + { + SSL_CTX_set_security_level(ctx->ctx, 1); + } + else if (0 == strcmp(profile, "preferred")) + { + SSL_CTX_set_security_level(ctx->ctx, 2); + } + else if (0 == strcmp(profile, "suiteb")) + { + SSL_CTX_set_security_level(ctx->ctx, 3); + SSL_CTX_set_cipher_list(ctx->ctx, "SUITEB128"); + } + else + { + msg(M_FATAL, "ERROR: Invalid cert profile: %s", profile); + } +#else + if (profile) + { + msg(M_WARN, "WARNING: OpenSSL 1.0.1 does not support --tls-cert-profile" + ", ignoring user-set profile: '%s'", profile); + } +#endif +} + void tls_ctx_check_cert_time(const struct tls_root_ctx *ctx) { @@ -1722,7 +1756,8 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) } void -show_available_tls_ciphers(const char *cipher_list) +show_available_tls_ciphers(const char *cipher_list, + const char *tls_cert_profile) { struct tls_root_ctx tls_ctx; SSL *ssl; @@ -1742,6 +1777,7 @@ show_available_tls_ciphers(const char *cipher_list) crypto_msg(M_FATAL, "Cannot create SSL object"); } + tls_ctx_set_cert_profile(&tls_ctx, tls_cert_profile); tls_ctx_restrict_ciphers(&tls_ctx, cipher_list); printf("Available TLS Ciphers,\n");