diff mbox

[2/3] TLS: Add tls_connection_params.openssl_ecdh_curves

Message ID 1492695635.2148.12.camel@venev.name
State Accepted
Headers show

Commit Message

Hristo Venev April 20, 2017, 1:40 p.m. UTC
Sorry, here's the patch:

TLS: Add tls_connection_params.openssl_ecdh_curves

OpenSSL needs server support for ECDH to be explicitly enabled.

Signed-off-by: Hristo Venev <hristo@venev.name>
---
 src/crypto/tls.h          |  3 +++
 src/crypto/tls_gnutls.c   |  5 +++++
 src/crypto/tls_internal.c |  6 ++++++
 src/crypto/tls_openssl.c  | 44 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 58 insertions(+)

Comments

Jouni Malinen Dec. 30, 2018, 4:41 p.m. UTC | #1
On Thu, Apr 20, 2017 at 02:40:35PM +0100, Hristo Venev wrote:
> OpenSSL needs server support for ECDH to be explicitly enabled.

Thanks, patches 2/3 and 3/3 applied with some cleanup and changes to
work with newer OpenSSL (and BoringSSL/LibreSSL) versions. It should be
noted that for Suite B, there is actually a different way of setting
ECDH parameters and latest OpenSSL versions enable automatic
determination of ECDH curves, so they should not actually need this new
functionality unless there is need to disable some curves.

I don't think I've seen an updated version of 1/3, so I dropped that one
from my queue.
diff mbox

Patch

diff --git a/src/crypto/tls.h b/src/crypto/tls.h
index 5859a6287..ccecddf63 100644
--- a/src/crypto/tls.h
+++ b/src/crypto/tls.h
@@ -137,6 +137,8 @@  struct tls_config {
  * @cert_id: the certificate's id when using engine
  * @ca_cert_id: the CA certificate's id when using engine
  * @openssl_ciphers: OpenSSL cipher configuration
+ * @openssl_ecdh_curves: OpenSSL ECDH curve configuration. NULL for auto if
+ *  supported, empty string to disable, or a colon-separated curve list.
  * @flags: Parameter options (TLS_CONN_*)
  * @ocsp_stapling_response: DER encoded file with cached OCSP stapling response
  *	or %NULL if OCSP is not enabled
@@ -180,6 +182,7 @@  struct tls_connection_params {
 	const char *cert_id;
 	const char *ca_cert_id;
 	const char *openssl_ciphers;
+	const char *openssl_ecdh_curves;
 
 	unsigned int flags;
 	const char *ocsp_stapling_response;
diff --git a/src/crypto/tls_gnutls.c b/src/crypto/tls_gnutls.c
index 8c76bfad4..71f92c28b 100644
--- a/src/crypto/tls_gnutls.c
+++ b/src/crypto/tls_gnutls.c
@@ -402,6 +402,11 @@  int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
 		return -1;
 	}
 
+	if (params->openssl_ecdh_curves) {
+		wpa_printf(MSG_INFO, "GnuTLS: openssl_ecdh_curves not supported");
+		return -1;
+	}
+
 	/* TODO: gnutls_certificate_set_verify_flags(xcred, flags);
 	 * to force peer validation(?) */
 
diff --git a/src/crypto/tls_internal.c b/src/crypto/tls_internal.c
index c7cb5ded3..b4fc0b7c6 100644
--- a/src/crypto/tls_internal.c
+++ b/src/crypto/tls_internal.c
@@ -240,6 +240,12 @@  int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
 		return -1;
 	}
 
+	if (params->openssl_ecdh_curves) {
+		wpa_printf(MSG_INFO, "TLS: openssl_ecdh_curves not supported");
+		tlsv1_cred_free(cred);
+		return -1;
+	}
+
 	if (tlsv1_set_ca_cert(cred, params->ca_cert,
 			      params->ca_cert_blob, params->ca_cert_blob_len,
 			      params->ca_path)) {
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index eddca859b..d45376043 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -4057,6 +4057,28 @@  int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
 		return -1;
 	}
 
+	if (params->openssl_ecdh_curves == NULL) {
+		#ifndef OPENSSL_NO_EC
+		if (SSL_set_ecdh_auto(conn->ssl, 1) != 1) {
+			wpa_printf(MSG_INFO,
+				   "OpenSSL: Failed to set ECDH curves to auto");
+			return -1;
+		}
+		#endif
+	} else if (params->openssl_ecdh_curves[0] != 0) {
+		#ifndef OPENSSL_NO_EC
+		if (SSL_set1_curves_list(conn->ssl, params->openssl_ecdh_curves) != 1) {
+			wpa_printf(MSG_INFO,
+				   "OpenSSL: Failed to set ECDH curves to auto");
+			return -1;
+		}
+		#else
+		wpa_printf(MSG_INFO,
+			   "OpenSSL: ECDH not supporrted");
+		return -1;
+		#endif
+	}
+
 	tls_set_conn_flags(conn->ssl, params->flags);
 
 #ifdef OPENSSL_IS_BORINGSSL
@@ -4121,6 +4143,28 @@  int tls_global_set_params(void *tls_ctx,
 		return -1;
 	}
 
+	if (params->openssl_ecdh_curves == NULL) {
+		#ifndef OPENSSL_NO_EC
+		if (SSL_CTX_set_ecdh_auto(ssl_ctx, 1) != 1) {
+			wpa_printf(MSG_INFO,
+				   "OpenSSL: Failed to set ECDH curves to auto");
+			return -1;
+		}
+		#endif
+	} else if (params->openssl_ecdh_curves[0] != 0) {
+		#ifndef OPENSSL_NO_EC
+		if (SSL_CTX_set1_curves_list(ssl_ctx, params->openssl_ecdh_curves) != 1) {
+			wpa_printf(MSG_INFO,
+				   "OpenSSL: Failed to set ECDH curves to auto");
+			return -1;
+		}
+		#else
+		wpa_printf(MSG_INFO,
+			   "OpenSSL: ECDH not supporrted");
+		return -1;
+		#endif
+	}
+
 #ifdef SSL_OP_NO_TICKET
 	if (params->flags & TLS_CONN_DISABLE_SESSION_TICKET)
 		SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TICKET);