tls: add CURLOPT_SSL_EC_CURVES and --curves

Closes #5892
This commit is contained in:
Michael Baentsch 2020-08-29 14:09:24 +02:00 committed by Daniel Stenberg
parent a337355487
commit ede125b7b7
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
20 changed files with 131 additions and 1 deletions

View File

@ -41,6 +41,7 @@ DPAGES = \
cookie.d \
create-dirs.d \
crlf.d crlfile.d \
curves.d \
data-ascii.d \
data-binary.d \
data-urlencode.d \

View File

@ -0,0 +1,17 @@
Long: curves
Arg: <algorithm list>
Help: (EC) TLS key exchange algorithm(s) to request
Protocols: TLS
Added: 7.73.0
---
Tells curl to request specific curves to use during SSL session establishment
according to RFC 8422, 5.1. Multiple algorithms can be provided by separating
them with ":" (e.g. "X25519:P-521"). The parameter is available identically
in the "openssl s_client/s_server" utilities.
--curves allows a OpenSSL powered curl to make SSL-connections with exactly
the (EC) curve requested by the client, avoiding intransparent client/server
negotiations.
If this option is set, the default curves list built into openssl will be
ignored.

View File

@ -532,6 +532,8 @@ Proxy client key type. See \fICURLOPT_PROXY_SSLKEYTYPE(3)\fP
Client key password. See \fICURLOPT_KEYPASSWD(3)\fP
.IP CURLOPT_PROXY_KEYPASSWD
Proxy client key password. See \fICURLOPT_PROXY_KEYPASSWD(3)\fP
.IP CURLOPT_SSL_EC_CURVES
Set key exchange curves. See \fICURLOPT_SSL_EC_CURVES(3)\fP
.IP CURLOPT_SSL_ENABLE_ALPN
Enable use of ALPN. See \fICURLOPT_SSL_ENABLE_ALPN(3)\fP
.IP CURLOPT_SSL_ENABLE_NPN

View File

@ -0,0 +1,54 @@
.\" **************************************************************************
.\" * _ _ ____ _
.\" * Project ___| | | | _ \| |
.\" * / __| | | | |_) | |
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
.\" * are also available at https://curl.haxx.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
.\" * furnished to do so, under the terms of the COPYING file.
.\" *
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
.\" * KIND, either express or implied.
.\" *
.\" **************************************************************************
.\"
.TH CURLOPT_SSL_EC_CURVES 3 "29 Aug 2020" "libcurl 7.73.0" "curl_easy_setopt options"
.SH NAME
CURLOPT_SSL_EC_CURVES \- set key exchange curves
.SH SYNOPSIS
#include <curl/curl.h>
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SSL_EC_CURVES, char *alg_list);
.SH DESCRIPTION
Pass a string as parameter with a colon delimited list of (EC) algorithms. This
option defines the client's key exchange algorithms in the SSL handshake (if
the SSL backend libcurl is built to use supports it).
.SH DEFAULT
"", embedded in SSL backend
.SH PROTOCOLS
HTTP
.SH EXAMPLE
.nf
CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
curl_easy_setopt(curl, CURLOPT_SSL_EC_CURVES, "X25519:P-521");
ret = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
.fi
.SH AVAILABILITY
Added in 7.73.0. Supported by the OpenSSL backend.
.SH RETURN VALUE
Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
.SH "SEE ALSO"
.BR CURLOPT_SSL_OPTIONS "(3), " CURLOPT_SSL_CIPHER_LIST "(3), "
.BR CURLOPT_TLS13_CIPHERS "(3), "

View File

@ -331,6 +331,7 @@ man_MANS = \
CURLOPT_SSL_CIPHER_LIST.3 \
CURLOPT_SSL_CTX_DATA.3 \
CURLOPT_SSL_CTX_FUNCTION.3 \
CURLOPT_SSL_EC_CURVES.3 \
CURLOPT_SSL_ENABLE_ALPN.3 \
CURLOPT_SSL_ENABLE_NPN.3 \
CURLOPT_SSL_FALSESTART.3 \

View File

@ -616,6 +616,7 @@ CURLOPT_SSLVERSION 7.1
CURLOPT_SSL_CIPHER_LIST 7.9
CURLOPT_SSL_CTX_DATA 7.10.6
CURLOPT_SSL_CTX_FUNCTION 7.10.6
CURLOPT_SSL_EC_CURVES 7.73.0
CURLOPT_SSL_ENABLE_ALPN 7.36.0
CURLOPT_SSL_ENABLE_NPN 7.36.0
CURLOPT_SSL_FALSESTART 7.42.0

View File

@ -32,6 +32,7 @@
--create-dirs 7.10.3
--crlf 5.7
--crlfile 7.19.7
--curves 7.73.0
--data (-d) 4.0
--data-ascii 7.2
--data-binary 7.2

View File

@ -2025,6 +2025,12 @@ typedef enum {
CURLOPT(CURLOPT_PROXY_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 296),
CURLOPT(CURLOPT_PROXY_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 297),
/* the EC curves requested by the TLS client (RFC 8422, 5.1);
* OpenSSL support via 'set_groups'/'set_curves':
* https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html
*/
CURLOPT(CURLOPT_SSL_EC_CURVES, CURLOPTTYPE_STRINGPOINT, 298),
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;

View File

@ -335,6 +335,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
(option) == CURLOPT_USERNAME || \
(option) == CURLOPT_USERPWD || \
(option) == CURLOPT_XOAUTH2_BEARER || \
(option) == CURLOPT_SSL_EC_CURVES || \
0)
/* evaluates to true if option takes a curl_write_callback argument */

View File

@ -349,6 +349,10 @@ static CURLcode dohprobe(struct Curl_easy *data,
ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx);
if(data->set.ssl.fsslctxp)
ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_DATA, data->set.ssl.fsslctxp);
if(data->set.str[STRING_SSL_EC_CURVES]) {
ERROR_CHECK_SETOPT(CURLOPT_SSL_EC_CURVES,
data->set.str[STRING_SSL_EC_CURVES]);
}
doh->set.fmultidone = Curl_doh_done;
doh->set.dohfor = data; /* identify for which transfer this is done */

View File

@ -278,6 +278,7 @@ struct curl_easyoption Curl_easyopts[] = {
{"SSL_CIPHER_LIST", CURLOPT_SSL_CIPHER_LIST, CURLOT_STRING, 0},
{"SSL_CTX_DATA", CURLOPT_SSL_CTX_DATA, CURLOT_CBPTR, 0},
{"SSL_CTX_FUNCTION", CURLOPT_SSL_CTX_FUNCTION, CURLOT_FUNCTION, 0},
{"SSL_EC_CURVES", CURLOPT_SSL_EC_CURVES, CURLOT_STRING, 0},
{"SSL_ENABLE_ALPN", CURLOPT_SSL_ENABLE_ALPN, CURLOT_LONG, 0},
{"SSL_ENABLE_NPN", CURLOPT_SSL_ENABLE_NPN, CURLOT_LONG, 0},
{"SSL_FALSESTART", CURLOPT_SSL_FALSESTART, CURLOT_LONG, 0},
@ -341,6 +342,6 @@ struct curl_easyoption Curl_easyopts[] = {
*/
int Curl_easyopts_check(void)
{
return (CURLOPT_LASTENTRY != (297 + 1));
return (CURLOPT_LASTENTRY != (298 + 1));
}
#endif

View File

@ -2241,6 +2241,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
break;
#endif
case CURLOPT_SSL_EC_CURVES:
/*
* Set accepted curves in SSL connection setup.
* Specify colon-delimited list of curve algorithm names.
*/
result = Curl_setstropt(&data->set.str[STRING_SSL_EC_CURVES],
va_arg(param, char *));
break;
#endif
case CURLOPT_IPRESOLVE:
arg = va_arg(param, long);

View File

@ -3616,6 +3616,7 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.ssl.primary.pinned_key =
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_ORIG];
data->set.ssl.primary.curves = data->set.str[STRING_SSL_EC_CURVES];
#ifndef CURL_DISABLE_PROXY
data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];

View File

@ -230,6 +230,7 @@ struct ssl_primary_config {
char *cipher_list13; /* list of TLS 1.3 cipher suites to use */
char *pinned_key;
struct curl_blob *cert_blob;
char *curves; /* list of curves to use */
BIT(verifypeer); /* set TRUE if this is desired */
BIT(verifyhost); /* set TRUE if CN/SAN must match hostname */
BIT(verifystatus); /* set TRUE if certificate status must be checked */
@ -1565,6 +1566,7 @@ enum dupstring {
STRING_DNS_INTERFACE,
STRING_DNS_LOCAL_IP4,
STRING_DNS_LOCAL_IP6,
STRING_SSL_EC_CURVES,
/* -- end of null-terminated strings -- */

View File

@ -200,6 +200,10 @@
!defined(OPENSSL_IS_BORINGSSL))
#define HAVE_SSL_CTX_SET_CIPHERSUITES
#define HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
/* SET_EC_CURVES available under the same preconditions: see
* https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html
*/
#define HAVE_SSL_CTX_SET_EC_CURVES
#endif
#if defined(LIBRESSL_VERSION_NUMBER)
@ -2800,6 +2804,18 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
SSL_CTX_set_post_handshake_auth(backend->ctx, 1);
#endif
#ifdef HAVE_SSL_CTX_SET_EC_CURVES
{
char *curves = SSL_CONN_CONFIG(curves);
if(curves) {
if(!SSL_CTX_set1_curves_list(backend->ctx, curves)) {
failf(data, "failed setting curves list: '%s'", curves);
return CURLE_SSL_CIPHER;
}
}
}
#endif
#ifdef HAVE_OPENSSL_SRP
if(ssl_authtype == CURL_TLSAUTH_SRP) {
char * const ssl_username = SSL_SET_OPTION(username);

View File

@ -138,6 +138,7 @@ Curl_ssl_config_matches(struct ssl_primary_config *data,
Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) &&
Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) &&
Curl_safe_strcasecompare(data->curves, needle->curves) &&
Curl_safe_strcasecompare(data->pinned_key, needle->pinned_key))
return TRUE;
@ -164,6 +165,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
CLONE_STRING(cipher_list);
CLONE_STRING(cipher_list13);
CLONE_STRING(pinned_key);
CLONE_STRING(curves);
return TRUE;
}
@ -179,6 +181,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc)
Curl_safefree(sslc->cipher_list13);
Curl_safefree(sslc->pinned_key);
Curl_safefree(sslc->cert_blob);
Curl_safefree(sslc->curves);
}
#ifdef USE_SSL

View File

@ -162,6 +162,7 @@ struct OperationConfig {
char *etag_compare_file;
bool crlf;
char *customrequest;
char *ssl_ec_curves;
char *krblevel;
char *request_target;
long httpversion;

View File

@ -272,6 +272,7 @@ static const struct LongShort aliases[]= {
{"EB", "socks5-gssapi", ARG_BOOL},
{"EC", "etag-save", ARG_FILENAME},
{"ED", "etag-compare", ARG_FILENAME},
{"EE", "curves", ARG_STRING},
{"f", "fail", ARG_BOOL},
{"fa", "fail-early", ARG_BOOL},
{"fb", "styled-output", ARG_BOOL},
@ -1726,6 +1727,10 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
GetStr(&config->etag_compare_file, nextarg);
break;
case 'E':
GetStr(&config->ssl_ec_curves, nextarg);
break;
default: /* unknown flag */
return PARAM_OPTION_UNKNOWN;
}

View File

@ -94,6 +94,8 @@ static const struct helptxt helptext[] = {
"Convert LF to CRLF in upload"},
{" --crlfile <file>",
"Get a CRL list in PEM format from the given file"},
{" --curves <algorithm list>",
"(EC) TLS key exchange algorithm(s) to request "},
{"-d, --data <data>",
"HTTP POST data"},
{" --data-ascii <data>",

View File

@ -1520,6 +1520,9 @@ static CURLcode single_transfer(struct GlobalConfig *global,
if(config->pinnedpubkey)
my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, config->pinnedpubkey);
if(config->ssl_ec_curves)
my_setopt_str(curl, CURLOPT_SSL_EC_CURVES, config->ssl_ec_curves);
if(curlinfo->features & CURL_VERSION_SSL) {
/* Check if config->cert is a PKCS#11 URI and set the
* config->cert_type if necessary */