diff --git a/src/crypto/tls.h b/src/crypto/tls.h index 481b34681..d6c581d03 100644 --- a/src/crypto/tls.h +++ b/src/crypto/tls.h @@ -144,6 +144,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 @@ -187,6 +189,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 36dafd260..5b52adb42 100644 --- a/src/crypto/tls_gnutls.c +++ b/src/crypto/tls_gnutls.c @@ -461,6 +461,12 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, } } + 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 d289c9442..3d2dcbbb1 100644 --- a/src/crypto/tls_internal.c +++ b/src/crypto/tls_internal.c @@ -248,6 +248,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 c2b0dfaec..808eb5772 100644 --- a/src/crypto/tls_openssl.c +++ b/src/crypto/tls_openssl.c @@ -4505,6 +4505,40 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, return -1; } + if (!params->openssl_ecdh_curves) { +#ifndef OPENSSL_IS_BORINGSSL +#ifndef OPENSSL_NO_EC +#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) && \ + (OPENSSL_VERSION_NUMBER < 0x10100000L) + if (SSL_set_ecdh_auto(conn->ssl, 1) != 1) { + wpa_printf(MSG_INFO, + "OpenSSL: Failed to set ECDH curves to auto"); + return -1; + } +#endif /* >= 1.0.2 && < 1.1.0 */ +#endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_IS_BORINGSSL */ + } else if (params->openssl_ecdh_curves[0]) { +#if defined(OPENSSL_IS_BORINGSSL) || (OPENSSL_VERSION_NUMBER < 0x10002000L) + wpa_printf(MSG_INFO, + "OpenSSL: ECDH configuration nnot supported"); + return -1; +#else /* OPENSSL_IS_BORINGSSL || < 1.0.2 */ +#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 '%s'", + params->openssl_ecdh_curves); + return -1; + } +#else /* OPENSSL_NO_EC */ + wpa_printf(MSG_INFO, "OpenSSL: ECDH not supported"); + return -1; +#endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_IS_BORINGSSL */ + } + if (tls_set_conn_flags(conn, params->flags, params->openssl_ciphers) < 0) return -1; @@ -4571,6 +4605,41 @@ int tls_global_set_params(void *tls_ctx, return -1; } + if (!params->openssl_ecdh_curves) { +#ifndef OPENSSL_IS_BORINGSSL +#ifndef OPENSSL_NO_EC +#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) && \ + (OPENSSL_VERSION_NUMBER < 0x10100000L) + 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 /* >= 1.0.2 && < 1.1.0 */ +#endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_IS_BORINGSSL */ + } else if (params->openssl_ecdh_curves[0]) { +#if defined(OPENSSL_IS_BORINGSSL) || (OPENSSL_VERSION_NUMBER < 0x10002000L) + wpa_printf(MSG_INFO, + "OpenSSL: ECDH configuration nnot supported"); + return -1; +#else /* OPENSSL_IS_BORINGSSL || < 1.0.2 */ +#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 '%s'", + params->openssl_ecdh_curves); + return -1; + } +#else /* OPENSSL_NO_EC */ + wpa_printf(MSG_INFO, "OpenSSL: ECDH not supported"); + return -1; +#endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_IS_BORINGSSL */ + } + #ifdef SSL_OP_NO_TICKET if (params->flags & TLS_CONN_DISABLE_SESSION_TICKET) SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TICKET); diff --git a/src/crypto/tls_wolfssl.c b/src/crypto/tls_wolfssl.c index cc8c70446..f86557e02 100644 --- a/src/crypto/tls_wolfssl.c +++ b/src/crypto/tls_wolfssl.c @@ -1524,6 +1524,12 @@ int tls_global_set_params(void *tls_ctx, return -1; } + if (params->openssl_ecdh_curves) { + wpa_printf(MSG_INFO, + "wolfSSL: openssl_ecdh_curves not supported"); + return -1; + } + #ifdef HAVE_SESSION_TICKET /* Session ticket is off by default - can't disable once on. */ if (!(params->flags & TLS_CONN_DISABLE_SESSION_TICKET))