From 564d88a8bd190a21b362d6da535fccf74d33394d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 2 Dec 2019 10:55:33 +0100 Subject: openssl: CURLSSLOPT_NO_PARTIALCHAIN can disable partial cert chains Closes #4655 --- docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 | 38 ++++++++++++++++++--------------- docs/libcurl/symbols-in-versions | 1 + include/curl/curl.h | 4 ++++ lib/setopt.c | 1 + lib/urldata.h | 1 + lib/vtls/openssl.c | 14 ++++++------ 6 files changed, 36 insertions(+), 23 deletions(-) diff --git a/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 b/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 index ace496abc..fd8504fb6 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 +++ b/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 @@ -28,23 +28,27 @@ CURLOPT_SSL_OPTIONS \- set SSL behavior options CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SSL_OPTIONS, long bitmask); .SH DESCRIPTION -Pass a long with a bitmask to tell libcurl about specific SSL behaviors. - -\fICURLSSLOPT_ALLOW_BEAST\fP tells libcurl to not attempt to use any -workarounds for a security flaw in the SSL3 and TLS1.0 protocols. If this -option isn't used or this bit is set to 0, the SSL layer libcurl uses may use a -work-around for this flaw although it might cause interoperability problems -with some (older) SSL implementations. WARNING: avoiding this work-around -lessens the security, and by setting this option to 1 you ask for exactly that. -This option is only supported for DarwinSSL, NSS and OpenSSL. - -Added in 7.44.0: - -\fICURLSSLOPT_NO_REVOKE\fP tells libcurl to disable certificate revocation -checks for those SSL backends where such behavior is present. This option is -only supported for Schannel (the native Windows SSL library), with an -exception in the case of Windows' Untrusted Publishers blacklist which it -seems can't be bypassed. +Pass a long with a bitmask to tell libcurl about specific SSL +behaviors. Available bits: +.IP CURLSSLOPT_ALLOW_BEAST +Tells libcurl to not attempt to use any workarounds for a security flaw in the +SSL3 and TLS1.0 protocols. If this option isn't used or this bit is set to 0, +the SSL layer libcurl uses may use a work-around for this flaw although it +might cause interoperability problems with some (older) SSL +implementations. WARNING: avoiding this work-around lessens the security, and +by setting this option to 1 you ask for exactly that. This option is only +supported for DarwinSSL, NSS and OpenSSL. +.IP CURLSSLOPT_NO_REVOKE +Tells libcurl to disable certificate revocation checks for those SSL backends +where such behavior is present. This option is only supported for Schannel +(the native Windows SSL library), with an exception in the case of Windows' +Untrusted Publishers blacklist which it seems can't be bypassed. (Added in +7.44.0) +.IP CURLSSLOPT_NO_PARTIALCHAIN +Tells libcurl to not accept "partial" certificate chains, which it otherwise +does by default. This option is only supported for OpenSSL and will fail the +certificate verification if the chain ends with an intermediate certificate +and not with a root cert. (Added in 7.68.0) .SH DEFAULT 0 .SH PROTOCOLS diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions index 29013b148..18f04bd70 100644 --- a/docs/libcurl/symbols-in-versions +++ b/docs/libcurl/symbols-in-versions @@ -738,6 +738,7 @@ CURLSSLBACKEND_SCHANNEL 7.34.0 CURLSSLBACKEND_SECURETRANSPORT 7.64.1 CURLSSLBACKEND_WOLFSSL 7.49.0 CURLSSLOPT_ALLOW_BEAST 7.25.0 +CURLSSLOPT_NO_PARTIALCHAIN 7.68.0 CURLSSLOPT_NO_REVOKE 7.44.0 CURLSSLSET_NO_BACKENDS 7.56.0 CURLSSLSET_OK 7.56.0 diff --git a/include/curl/curl.h b/include/curl/curl.h index a6d555819..bef8a0bca 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -828,6 +828,10 @@ typedef enum { SSL backends where such behavior is present. */ #define CURLSSLOPT_NO_REVOKE (1<<1) +/* - NO_PARTIALCHAIN tells libcurl to *NOT* accept a partial certificate chain + if possible. The OpenSSL backend has this ability. */ +#define CURLSSLOPT_NO_PARTIALCHAIN (1<<2) + /* The default connection attempt delay in milliseconds for happy eyeballs. CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document this value, keep them in sync. */ diff --git a/lib/setopt.c b/lib/setopt.c index 64c29e333..d7b9ca285 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -2133,6 +2133,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.ssl.enable_beast = (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE); data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); + data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN); break; #ifndef CURL_DISABLE_PROXY diff --git a/lib/urldata.h b/lib/urldata.h index a70b2b09a..3effb1626 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -257,6 +257,7 @@ struct ssl_config_data { BIT(falsestart); BIT(enable_beast); /* allow this flaw for interoperability's sake*/ BIT(no_revoke); /* disable SSL certificate revocation checks */ + BIT(no_partialchain); /* don't accept partial certificate chains */ }; struct ssl_general_config { diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index fb725716c..726ff6e7c 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -2786,12 +2786,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) X509_V_FLAG_TRUSTED_FIRST); #endif #ifdef X509_V_FLAG_PARTIAL_CHAIN - /* Have intermediate certificates in the trust store be treated as - trust-anchors, in the same way as self-signed root CA certificates - are. This allows users to verify servers using the intermediate cert - only, instead of needing the whole chain. */ - X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), - X509_V_FLAG_PARTIAL_CHAIN); + if(!SSL_SET_OPTION(no_partialchain)) { + /* Have intermediate certificates in the trust store be treated as + trust-anchors, in the same way as self-signed root CA certificates + are. This allows users to verify servers using the intermediate cert + only, instead of needing the whole chain. */ + X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), + X509_V_FLAG_PARTIAL_CHAIN); + } #endif } -- cgit v1.2.3