[2/3] TLS: Add tls_connection_params.openssl_ecdh_curves

Submitted by Hristo Venev on April 20, 2017, 1:40 p.m.

Details

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

Commit Message

Hristo Venev April 20, 2017, 1:40 p.m.
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(+)

Patch hide | download patch | download mbox

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);