summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJay Satiro <raysatiro@yahoo.com>2021-02-27 16:27:31 -0500
committerJay Satiro <raysatiro@yahoo.com>2021-04-22 16:53:37 -0400
commit54e747501626b81149b1b44949119d365db82004 (patch)
tree6c89f73c8eb7bbb96877a83e27b3b3916d5534e7 /lib
parente4ba999646ed7a974813ecf8405651d300554eba (diff)
downloadcurl-54e747501626b81149b1b44949119d365db82004.tar.gz
schannel: Disable auto credentials; add an option to enable it
- Disable auto credentials by default. This is a breaking change for clients that are using it, wittingly or not. - New libcurl ssl option value CURLSSLOPT_AUTO_CLIENT_CERT tells libcurl to automatically locate and use a client certificate for authentication, when requested by the server. - New curl tool options --ssl-auto-client-cert and --proxy-ssl-auto-client-cert map to CURLSSLOPT_AUTO_CLIENT_CERT. This option is only supported for Schannel (the native Windows SSL library). Prior to this change Schannel would, with no notification to the client, attempt to locate a client certificate and send it to the server, when requested by the server. Since the server can request any certificate that supports client authentication in the OS certificate store it could be a privacy violation and unexpected. Fixes https://github.com/curl/curl/issues/2262 Reported-by: Jeroen Ooms Assisted-by: Wes Hinsley Assisted-by: Rich FitzJohn Ref: https://curl.se/mail/lib-2021-02/0066.html Reported-by: Morten Minde Neergaard Closes https://github.com/curl/curl/pull/6673
Diffstat (limited to 'lib')
-rw-r--r--lib/doh.c5
-rw-r--r--lib/setopt.c5
-rw-r--r--lib/urldata.h2
-rw-r--r--lib/vtls/schannel.c19
4 files changed, 24 insertions, 7 deletions
diff --git a/lib/doh.c b/lib/doh.c
index 52388cba3..8ea53ff8d 100644
--- a/lib/doh.c
+++ b/lib/doh.c
@@ -351,7 +351,10 @@ static CURLcode dohprobe(struct Curl_easy *data,
(data->set.ssl.revoke_best_effort ?
CURLSSLOPT_REVOKE_BEST_EFFORT : 0) |
(data->set.ssl.native_ca_store ?
- CURLSSLOPT_NATIVE_CA : 0);
+ CURLSSLOPT_NATIVE_CA : 0) |
+ (data->set.ssl.auto_client_cert ?
+ CURLSSLOPT_AUTO_CLIENT_CERT : 0);
+
curl_easy_setopt(doh, CURLOPT_SSL_OPTIONS, mask);
}
diff --git a/lib/setopt.c b/lib/setopt.c
index ff6cb4276..16b83321d 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -2290,6 +2290,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN);
data->set.ssl.revoke_best_effort = !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT);
data->set.ssl.native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA);
+ data->set.ssl.auto_client_cert = !!(arg & CURLSSLOPT_AUTO_CLIENT_CERT);
/* If a setting is added here it should also be added in dohprobe()
which sets its own CURLOPT_SSL_OPTIONS based on these settings. */
break;
@@ -2301,9 +2302,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
(bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE);
data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
data->set.proxy_ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN);
- data->set.proxy_ssl.native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA);
data->set.proxy_ssl.revoke_best_effort =
!!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT);
+ data->set.proxy_ssl.native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA);
+ data->set.proxy_ssl.auto_client_cert =
+ !!(arg & CURLSSLOPT_AUTO_CLIENT_CERT);
break;
#endif
diff --git a/lib/urldata.h b/lib/urldata.h
index b7b17e30c..c8797698a 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -286,6 +286,8 @@ struct ssl_config_data {
BIT(revoke_best_effort); /* ignore SSL revocation offline/missing revocation
list errors */
BIT(native_ca_store); /* use the native ca store of operating system */
+ BIT(auto_client_cert); /* automatically locate and use a client
+ certificate for authentication (Schannel) */
};
struct ssl_general_config {
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index b944bbd49..7d96cf7fc 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -553,6 +553,20 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
"names in server certificates.\n"));
}
+ /* security request flags */
+ BACKEND->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
+ ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
+ ISC_REQ_STREAM;
+
+ if(!SSL_SET_OPTION(auto_client_cert)) {
+ schannel_cred.dwFlags &= ~SCH_CRED_USE_DEFAULT_CREDS;
+ schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS;
+ BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
+ infof(data, "schannel: disabled automatic use of client certificate\n");
+ }
+ else
+ infof(data, "schannel: enabled automatic use of client certificate\n");
+
switch(conn->ssl_config.version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
@@ -886,11 +900,6 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
- /* setup request flags */
- BACKEND->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
- ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
- ISC_REQ_STREAM;
-
/* allocate memory for the security context handle */
BACKEND->ctxt = (struct Curl_schannel_ctxt *)
calloc(1, sizeof(struct Curl_schannel_ctxt));