- { build: 'cmake' , sys: 'clang64' , env: 'clang-x86_64' , tflags: '' , config: '-DENABLE_DEBUG=ON -DBUILD_SHARED_LIBS=OFF -DCURL_USE_GNUTLS=ON -DENABLE_UNICODE=OFF -DUSE_NGTCP2=ON -DCURL_USE_LIBSSH2=OFF -DCURL_USE_LIBSSH=ON', install: 'mingw-w64-clang-x86_64-gnutls mingw-w64-clang-x86_64-nghttp3 mingw-w64-clang-x86_64-ngtcp2 mingw-w64-clang-x86_64-libssh', type: 'Debug', name: 'gnutls libssh' }
- { build: 'cmake' , sys: 'clangarm64', env: 'clang-aarch64', tflags: 'skiprun', config: '-DENABLE_DEBUG=OFF -DBUILD_SHARED_LIBS=ON -DCURL_USE_SCHANNEL=ON -DENABLE_UNICODE=ON -DENABLE_CURLDEBUG=ON', install: 'mingw-w64-clang-aarch64-libssh2', type: 'Release', name: 'schannel R TrackMemory', image: 'windows-11-arm' }
- { build: 'cmake' , sys: 'clang64' , env: 'clang-x86_64' , tflags: 'skiprun', config: '-DENABLE_DEBUG=ON -DBUILD_SHARED_LIBS=OFF -DCURL_USE_OPENSSL=ON -DENABLE_UNICODE=OFF -DUSE_NGTCP2=ON', install: 'mingw-w64-clang-x86_64-openssl mingw-w64-clang-x86_64-nghttp3 mingw-w64-clang-x86_64-ngtcp2 mingw-w64-clang-x86_64-libssh2', type: 'Release', name: 'openssl', chkprefill: '_chkprefill' }
- - { build: 'cmake' , sys: 'ucrt64' , env: 'ucrt-x86_64' , tflags: 'skiprun', config: '-DENABLE_DEBUG=OFF -DBUILD_SHARED_LIBS=ON -DCURL_USE_SCHANNEL=ON', install: 'mingw-w64-ucrt-x86_64-libssh2', type: 'Release', test: 'uwp', name: 'schannel' }
+ - { build: 'cmake' , sys: 'ucrt64' , env: 'ucrt-x86_64' , tflags: 'skiprun', config: '-DENABLE_DEBUG=OFF -DBUILD_SHARED_LIBS=ON -DCURL_USE_OPENSSL=ON', install: 'mingw-w64-ucrt-x86_64-openssl mingw-w64-ucrt-x86_64-libssh2', type: 'Release', test: 'uwp', name: 'schannel' }
# { build: 'autotools', sys: 'ucrt64' , env: 'ucrt-x86_64' , tflags: 'skiprun', config: '--without-debug --with-schannel --enable-shared', install: 'mingw-w64-ucrt-x86_64-libssh2', type: 'Release', test: 'uwp', name: 'schannel' }
- { build: 'cmake' , sys: 'mingw64' , env: 'x86_64' , tflags: 'skiprun', config: '-DENABLE_DEBUG=ON -DBUILD_SHARED_LIBS=ON -DCURL_USE_SCHANNEL=ON -DENABLE_UNICODE=ON -DCMAKE_VERBOSE_MAKEFILE=ON', install: 'mingw-w64-x86_64-libssh2', type: 'Debug', cflags: '-DCURL_SCHANNEL_DEV_DEBUG', name: 'schannel dev debug', image: 'windows-2025' }
- { build: 'cmake' , sys: 'mingw32' , env: 'i686' , tflags: 'skiprun', config: '-DENABLE_DEBUG=OFF -DBUILD_SHARED_LIBS=ON -DCURL_USE_SCHANNEL=ON -DENABLE_UNICODE=ON', install: 'mingw-w64-i686-libssh2', type: 'Release', name: 'schannel R' }
AC_MSG_RESULT(yes)
)
-dnl ************************************************************
-dnl enable SSPI support
-dnl
-AC_MSG_CHECKING([whether to enable SSPI support (Windows native builds only)])
-AC_ARG_ENABLE(sspi,
-AS_HELP_STRING([--enable-sspi],[Enable SSPI])
-AS_HELP_STRING([--disable-sspi],[Disable SSPI]),
-[ case "$enableval" in
- yes)
- if test "$curl_cv_native_windows" = "yes"; then
- AC_MSG_RESULT(yes)
- AC_DEFINE(USE_WINDOWS_SSPI, 1, [to enable SSPI support])
- USE_WINDOWS_SSPI=1
- curl_sspi_msg="enabled"
- else
- AC_MSG_RESULT(no)
- AC_MSG_WARN([--enable-sspi Ignored. Only supported on native Windows builds.])
- fi
- ;;
- *)
- if test "x$SCHANNEL_ENABLED" = "x1"; then
- # --with-schannel implies --enable-sspi
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
- ;;
- esac ],
- if test "x$SCHANNEL_ENABLED" = "x1"; then
- # --with-schannel implies --enable-sspi
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
-)
+if test "$curl_cv_winuwp" != 'yes'; then
+ dnl ************************************************************
+ dnl enable SSPI support
+ dnl
+ AC_MSG_CHECKING([whether to enable SSPI support (Windows native builds only)])
+ AC_ARG_ENABLE(sspi,
+ AS_HELP_STRING([--enable-sspi],[Enable SSPI])
+ AS_HELP_STRING([--disable-sspi],[Disable SSPI]),
+ [ case "$enableval" in
+ yes)
+ if test "$curl_cv_native_windows" = "yes"; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(USE_WINDOWS_SSPI, 1, [to enable SSPI support])
+ USE_WINDOWS_SSPI=1
+ curl_sspi_msg="enabled"
+ else
+ AC_MSG_RESULT(no)
+ AC_MSG_WARN([--enable-sspi Ignored. Only supported on native Windows builds.])
+ fi
+ ;;
+ *)
+ if test "x$SCHANNEL_ENABLED" = "x1"; then
+ # --with-schannel implies --enable-sspi
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ ;;
+ esac ],
+ if test "x$SCHANNEL_ENABLED" = "x1"; then
+ # --with-schannel implies --enable-sspi
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ )
-if test "x$USE_WINDOWS_SSPI" = "x1"; then
- LIBS="-lsecur32 $LIBS"
+ if test "x$USE_WINDOWS_SSPI" = "x1"; then
+ LIBS="-lsecur32 $LIBS"
+ fi
fi
dnl ************************************************************
#define CERT_FIND_HAS_PRIVATE_KEY (21 << CERT_COMPARE_SHIFT)
#endif
+/* key to use at `multi->proto_hash` */
+#define MPROTO_SCHANNEL_CERT_SHARE_KEY "tls:schannel:cert:share"
+
/* ALPN requires version 8.1 of the Windows SDK, which was
shipped with Visual Studio 2013, aka _MSC_VER 1800:
https://technet.microsoft.com/en-us/library/hh831771%28v=ws.11%29.aspx
return CURLE_OK;
}
-#ifdef HAS_CLIENT_CERT_PATH
-
+#ifndef UNDER_CE
/* Function allocates memory for store_path only if CURLE_OK is returned */
static CURLcode
get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
-#ifdef HAS_CLIENT_CERT_PATH
PCCERT_CONTEXT client_certs[1] = { NULL };
HCERTSTORE client_cert_store = NULL;
-#endif
SECURITY_STATUS sspi_status = SEC_E_OK;
CURLcode result;
DEBUGASSERT(backend);
if(conn_config->verifypeer) {
-#ifdef HAS_MANUAL_VERIFY_API
if(backend->use_manual_cred_validation)
flags = SCH_CRED_MANUAL_CRED_VALIDATION;
else
-#endif
flags = SCH_CRED_AUTO_CRED_VALIDATION;
if(ssl_config->no_revoke) {
return CURLE_SSL_CONNECT_ERROR;
}
-#ifdef HAS_CLIENT_CERT_PATH
+#ifndef UNDER_CE
/* client certificate */
if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) {
DWORD cert_store_name = 0;
}
client_cert_store = cert_store;
}
-#else
- if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) {
- failf(data, "schannel: client cert support not built in");
- return CURLE_NOT_BUILT_IN;
- }
#endif
/* allocate memory for the reusable credential handle */
if(!backend->cred) {
failf(data, "schannel: unable to allocate memory");
-#ifdef HAS_CLIENT_CERT_PATH
if(client_certs[0])
CertFreeCertificateContext(client_certs[0]);
if(client_cert_store)
CertCloseStore(client_cert_store, 0);
-#endif
return CURLE_OUT_OF_MEMORY;
}
backend->cred->refcount = 1;
-#ifdef HAS_CLIENT_CERT_PATH
/* Since we did not persist the key, we need to extend the store's
* lifetime until the end of the connection
*/
backend->cred->client_cert_store = client_cert_store;
-#endif
/* We support TLS 1.3 starting in Windows 10 version 1809 (OS build 17763) as
long as the user did not set a legacy algorithm list
credentials.pTlsParameters->grbitDisabledProtocols =
(DWORD)~enabled_protocols;
-#ifdef HAS_CLIENT_CERT_PATH
if(client_certs[0]) {
credentials.cCreds = 1;
credentials.paCred = client_certs;
}
-#endif
sspi_status =
Curl_pSecFn->AcquireCredentialsHandle(NULL,
schannel_cred.dwFlags = flags | SCH_USE_STRONG_CRYPTO;
}
-#ifdef HAS_CLIENT_CERT_PATH
if(client_certs[0]) {
schannel_cred.cCreds = 1;
schannel_cred.paCred = client_certs;
}
-#endif
sspi_status =
Curl_pSecFn->AcquireCredentialsHandle(NULL,
&backend->cred->time_stamp);
}
-#ifdef HAS_CLIENT_CERT_PATH
if(client_certs[0])
CertFreeCertificateContext(client_certs[0]);
-#endif
if(sspi_status != SEC_E_OK) {
char buffer[STRERROR_LEN];
#endif
#ifdef UNDER_CE
-#ifdef HAS_MANUAL_VERIFY_API
/* certificate validation on Windows CE does not seem to work right; we will
* do it following a more manual process. */
backend->use_manual_cred_validation = TRUE;
#else
-#error "compiler too old to support Windows CE requisite manual cert verify"
-#endif
-#else
-#ifdef HAS_MANUAL_VERIFY_API
if(conn_config->CAfile || conn_config->ca_info_blob) {
if(curlx_verify_windows_version(6, 1, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) {
}
else
backend->use_manual_cred_validation = FALSE;
-#else
- if(conn_config->CAfile || conn_config->ca_info_blob) {
- failf(data, "schannel: CA cert support not built in");
- return CURLE_NOT_BUILT_IN;
- }
-#endif
#endif
backend->cred = NULL;
failf(data, "schannel: SNI or certificate check failed: %s",
Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
return CURLE_PEER_FAILED_VERIFICATION;
- /*
- case SEC_E_INVALID_HANDLE:
- case SEC_E_INVALID_TOKEN:
- case SEC_E_LOGON_DENIED:
- case SEC_E_TARGET_UNKNOWN:
- case SEC_E_NO_AUTHENTICATING_AUTHORITY:
- case SEC_E_INTERNAL_ERROR:
- case SEC_E_NO_CREDENTIALS:
- case SEC_E_UNSUPPORTED_FUNCTION:
- case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
- */
+#if 0
+ case SEC_E_INVALID_HANDLE:
+ case SEC_E_INVALID_TOKEN:
+ case SEC_E_LOGON_DENIED:
+ case SEC_E_TARGET_UNKNOWN:
+ case SEC_E_NO_AUTHENTICATING_AUTHORITY:
+ case SEC_E_INTERNAL_ERROR:
+ case SEC_E_NO_CREDENTIALS:
+ case SEC_E_UNSUPPORTED_FUNCTION:
+ case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
+#endif
default:
failf(data, "schannel: initial InitializeSecurityContext failed: %s",
Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
}
}
-#ifdef HAS_MANUAL_VERIFY_API
if(conn_config->verifypeer && backend->use_manual_cred_validation) {
/* Certificate verification also verifies the hostname if verifyhost */
return Curl_verify_certificate(cf, data);
}
-#endif
/* Verify the hostname manually when certificate verification is disabled,
because in that case Schannel will not verify it. */
if(cred->refcount == 0) {
Curl_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
curlx_unicodefree(cred->sni_hostname);
-#ifdef HAS_CLIENT_CERT_PATH
if(cred->client_cert_store) {
CertCloseStore(cred->client_cert_store, 0);
cred->client_cert_store = NULL;
}
-#endif
Curl_safefree(cred);
}
}
static int schannel_init(void)
{
#if defined(HAS_ALPN_SCHANNEL) && !defined(UNDER_CE)
- bool wine = FALSE;
- bool wine_has_alpn = FALSE;
-
-#ifndef CURL_WINDOWS_UWP
typedef const char *(APIENTRY *WINE_GET_VERSION_FN)(void);
- /* GetModuleHandle() not available for UWP.
- Assume no WINE because WINE has no UWP support. */
WINE_GET_VERSION_FN p_wine_get_version =
CURLX_FUNCTION_CAST(WINE_GET_VERSION_FN,
(GetProcAddress(GetModuleHandleA("ntdll"),
"wine_get_version")));
- wine = !!p_wine_get_version;
- if(wine) {
+ if(p_wine_get_version) { /* WINE detected */
const char *wine_version = p_wine_get_version(); /* e.g. "6.0.2" */
/* Assume ALPN support with WINE 6.0 or upper */
- wine_has_alpn = wine_version && atoi(wine_version) >= 6;
+ s_win_has_alpn = wine_version && atoi(wine_version) >= 6;
}
-#endif
- if(wine)
- s_win_has_alpn = wine_has_alpn;
else {
/* ALPN is supported on Windows 8.1 / Server 2012 R2 and above. */
s_win_has_alpn = curlx_verify_windows_version(6, 3, 0, PLATFORM_WINNT,
DWORD provType,
const unsigned int algId)
{
-#ifdef CURL_WINDOWS_UWP
- (void)input;
- (void)inputlen;
- (void)provType;
- (void)algId;
- memset(checksum, 0, checksumlen);
-#else
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
DWORD cbHashSize = 0;
if(hProv)
CryptReleaseContext(hProv, 0);
-#endif
}
static CURLcode schannel_sha256sum(const unsigned char *input,
{ CURLSSLBACKEND_SCHANNEL, "schannel" }, /* info */
SSLSUPP_CERTINFO |
-#ifdef HAS_MANUAL_VERIFY_API
SSLSUPP_CAINFO_BLOB |
-#endif
-#ifndef CURL_WINDOWS_UWP
SSLSUPP_PINNEDPUBKEY |
-#endif
SSLSUPP_CA_CACHE |
SSLSUPP_HTTPS_PROXY |
SSLSUPP_CIPHER_LIST,