ssl-allow-beast.d \
ssl-no-revoke.d \
ssl-reqd.d \
+ ssl-revoke-best-effort.d \
ssl.d \
sslv2.d sslv3.d \
stderr.d \
--- /dev/null
+Long: ssl-revoke-best-effort
+Help: Ignore missing/offline cert CRL distribution points (Schannel)
+Added: 7.70.0
+---
+(Schannel) This option tells curl to ignore certificate revocation checks when
+they failed due to missing/offline distribution points for the revocation check
+lists.
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)
+
+.IP CURLSSLOPT_REVOKE_BEST_EFFORT
+Tells libcurl to ignore certificate revocation checks in case of missing or
+offline distribution points for those SSL backends where such behavior is
+present. This option is only supported for Schannel (the native Windows SSL
+library). If combined with \fICURLSSLOPT_NO_REVOKE\fP, the latter takes
+precedence. (Added in 7.70.0)
.SH DEFAULT
0
.SH PROTOCOLS
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)
+.IP CURLSSLOPT_REVOKE_BEST_EFFORT
+Tells libcurl to ignore certificate revocation checks in case of missing or
+offline distribution points for those SSL backends where such behavior is
+present. This option is only supported for Schannel (the native Windows SSL
+library). If combined with \fICURLSSLOPT_NO_REVOKE\fP, the latter takes
+precedence. (Added in 7.70.0)
.SH DEFAULT
0
.SH PROTOCOLS
CURLSSLOPT_NO_REVOKE 7.44.0
CURLSSLSET_NO_BACKENDS 7.56.0
CURLSSLSET_OK 7.56.0
+CURLSSLOPT_REVOKE_BEST_EFFORT 7.70.0
CURLSSLSET_TOO_LATE 7.56.0
CURLSSLSET_UNKNOWN_BACKEND 7.56.0
CURLUE_BAD_HANDLE 7.62.0
if possible. The OpenSSL backend has this ability. */
#define CURLSSLOPT_NO_PARTIALCHAIN (1<<2)
+/* - REVOKE_BEST_EFFORT tells libcurl to ignore certificate revocation offline
+ checks and ignore missing revocation list for those SSL backends where such
+ behavior is present. */
+#define CURLSSLOPT_REVOKE_BEST_EFFORT (1<<3)
+
/* 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. */
}
if(data->set.proxy_ssl.no_revoke)
ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
+ else if(data->set.proxy_ssl.revoke_best_effort)
+ ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS,
+ CURLSSLOPT_REVOKE_BEST_EFFORT);
if(data->set.str[STRING_SSL_CAPATH_PROXY]) {
ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAPATH,
data->set.str[STRING_SSL_CAPATH_PROXY]);
}
if(data->set.ssl.no_revoke)
ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
+ else if(data->set.ssl.revoke_best_effort)
+ ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_REVOKE_BEST_EFFORT);
if(data->set.ssl.fsslctx)
ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx);
if(data->set.ssl.fsslctxp)
(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);
+ data->set.ssl.revoke_best_effort = !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT);
break;
#ifndef CURL_DISABLE_PROXY
(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.revoke_best_effort =
+ !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT);
break;
#endif
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 */
+ BIT(revoke_best_effort); /* ignore SSL revocation offline/missing revocation
+ list errors */
};
struct ssl_general_config {
DEBUGF(infof(data, "schannel: disabled server certificate revocation "
"checks\n"));
}
+ else if(data->set.ssl.revoke_best_effort) {
+ schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+ SCH_CRED_IGNORE_REVOCATION_OFFLINE | SCH_CRED_REVOCATION_CHECK_CHAIN;
+
+ DEBUGF(infof(data, "schannel: ignore revocation offline errors"));
+ }
else {
schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
+
DEBUGF(infof(data,
"schannel: checking server certificate revocation\n"));
}
CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0];
DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED);
dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus;
+
+ if(data->set.ssl.revoke_best_effort) {
+ /* Ignore errors when root certificates are missing the revocation
+ * list URL, or when the list could not be downloaded because the
+ * server is currently unreachable. */
+ dwTrustErrorMask &= ~(DWORD)(CERT_TRUST_REVOCATION_STATUS_UNKNOWN |
+ CERT_TRUST_IS_OFFLINE_REVOCATION);
+ }
+
if(dwTrustErrorMask) {
if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED)
failf(data, "schannel: CertGetCertificateChain trust error"
d c X'0002'
d CURLSSLOPT_NO_PARTIALCHAIN...
d c X'0004'
+ d CURLSSLOPT_REVOKE_BEST_EFFORT...
+ d c X'0008'
*
d CURL_HET_DEFAULT...
d c 200
bool ssl_no_revoke; /* disable SSL certificate revocation checks */
/*bool proxy_ssl_no_revoke; */
+ bool ssl_revoke_best_effort; /* ignore SSL revocation offline/missing
+ revocation list errors */
+
bool use_metalink; /* process given URLs as metalink XML file */
metalinkfile *metalinkfile_list; /* point to the first node */
metalinkfile *metalinkfile_last; /* point to the last/current node */
{"Eq", "cert-status", ARG_BOOL},
{"Er", "false-start", ARG_BOOL},
{"Es", "ssl-no-revoke", ARG_BOOL},
+ {"ES", "ssl-revoke-best-effort", ARG_BOOL},
{"Et", "tcp-fastopen", ARG_BOOL},
{"Eu", "proxy-tlsuser", ARG_STRING},
{"Ev", "proxy-tlspassword", ARG_STRING},
config->ssl_no_revoke = TRUE;
break;
+ case 'S': /* --ssl-revoke-best-effort */
+ if(curlinfo->features & CURL_VERSION_SSL)
+ config->ssl_revoke_best_effort = TRUE;
+ break;
+
case 't': /* --tcp-fastopen */
config->tcp_fastopen = TRUE;
break;
"Allow security flaw to improve interop"},
{" --ssl-no-revoke",
"Disable cert revocation checks (Schannel)"},
+ {" --ssl-revoke-best-effort",
+ "Ignore revocation offline or missing revocation list errors (Schannel)"},
{" --ssl-reqd",
"Require SSL/TLS"},
{"-2, --sslv2",
my_setopt_str(curl, CURLOPT_GSSAPI_DELEGATION,
config->gssapi_delegation);
- /* new in 7.25.0 and 7.44.0 */
+ /* new in 7.25.0, 7.44.0 and 7.70.0 */
{
long mask = (config->ssl_allow_beast ? CURLSSLOPT_ALLOW_BEAST : 0) |
+ (config->ssl_revoke_best_effort ?
+ CURLSSLOPT_REVOKE_BEST_EFFORT : 0) |
(config->ssl_no_revoke ? CURLSSLOPT_NO_REVOKE : 0);
if(mask)
my_setopt_bitmask(curl, CURLOPT_SSL_OPTIONS, mask);
NV(CURLSSLOPT_ALLOW_BEAST),
NV(CURLSSLOPT_NO_REVOKE),
NV(CURLSSLOPT_NO_PARTIALCHAIN),
+ NV(CURLSSLOPT_REVOKE_BEST_EFFORT),
NVEND,
};
test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055 \
test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \
test2064 test2065 test2066 test2067 test2068 test2069 \
+test2064 test2065 test2066 test2067 test2068 test2069 test2070 \
test2071 test2072 test2073 test2074 test2075 test2076 test2077 \
test2078 \
test2080 \
--- /dev/null
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+PEM certificate
+</keywords>
+</info>type
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 7
+
+MooMoo
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+WinSSL
+!MinGW
+</features>
+<server>
+https Server-localhost-sv.pem
+</server>
+ <name>
+Ignore certificate revocation "best effort" strategy
+ </name>
+ <setenv>
+# This test is pointless if we're not using the schannel backend
+CURL_SSL_BACKEND=schannel
+ </setenv>
+ <command>
+--cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --ssl-revoke-best-effort https://localhost:%HTTPSPORT/2070
+</command>
+# Ensure that we're running on localhost because we're checking the host name
+<precheck>
+perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0.0.1' );"
+</precheck>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /2070 HTTP/1.1\r
+Host: localhost:%HTTPSPORT\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
my $has_multissl; # set if curl is build with MultiSSL support
my $has_manual; # set if curl is built with built-in manual
my $has_win32; # set if curl is built for Windows
+my $has_mingw; # set if curl is built with MinGW (as opposed to MinGW-w64)
# this version is decided by the particular nghttp2 library that is being used
my $h2cver = "h2c";
my $has_textaware; # set if running on a system that has a text mode concept
# on files. Windows for example
-
my @protocols; # array of lowercase supported protocol servers
my $skipped=0; # number of tests skipped; reported in main loop
$feature{"manual"} = $has_manual;
$feature{"unix-sockets"} = $has_unix;
$feature{"win32"} = $has_win32;
+ $feature{"MinGW"} = $has_mingw;
# make each protocol an enabled "feature"
for my $p (@protocols) {
$pwd = pathhelp::sys_native_current_path();
$has_textaware = 1;
$has_win32 = 1;
+ $has_mingw = 1 if ($curl =~ /-pc-mingw32/);
}
if ($libcurl =~ /(winssl|schannel)/i) {
$has_winssl=1;