schannel: not supported with UWP, drop redundant code

Schannel is not supported by UWP. SSPI is also required by Schannel in
curl, and SSPI also isn't supported by UWP.

mingw-w64 is able to create such build regardless (my guess: due to API
parts not accurately marked as UWP-only), but the binary is unlikely
to work. With MSVC the failure happens at build-time.

Ref: https://learn.microsoft.com/windows/win32/api/sspi/nf-sspi-initsecurityinterfacea#requirements
Ref: https://learn.microsoft.com/windows/win32/secauthn/initializesecuritycontext--schannel#requirements

Drop all UWP-related logic, including two related feature checks, that
can now be permanently enabled.

Also:
- build: show fatal error for Schannel in UWP mode.
- build: do not allow enabling SSPI in UWP mode.
- drop undocumented option `DISABLE_SCHANNEL_CLIENT_CERT`. Added without
  mention in an unrelated commit. The PR text says to save size. On x64
  this is 0.3%, or 4KB out of 1.3MB. The tiny gain doesn't justify
  an extra build variant. Ref: 8beff43559
- move `MPROTO_SCHANNEL_CERT_SHARE_KEY` closer to its use.
- replace commented block with `#if 0`.

Reviewed-by: Jay Satiro
Follow-up to cd0ec4784c #17089
Closes #18116
This commit is contained in:
Viktor Szakats 2025-07-31 07:44:35 +02:00
parent b5c245045e
commit 923db3515d
No known key found for this signature in database
GPG Key ID: B5ABD165E2AEF201
7 changed files with 65 additions and 152 deletions

View File

@ -213,7 +213,7 @@ jobs:
- { 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: '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: '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: '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: '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: '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' } - { 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' }

View File

@ -726,6 +726,9 @@ elseif(_enabled_ssl_options_count EQUAL 0)
endif() endif()
if(CURL_USE_SCHANNEL) if(CURL_USE_SCHANNEL)
if(WINDOWS_STORE)
message(FATAL_ERROR "UWP does not support Schannel.")
endif()
set(_ssl_enabled ON) set(_ssl_enabled ON)
set(USE_SCHANNEL ON) # Windows native SSL/TLS support set(USE_SCHANNEL ON) # Windows native SSL/TLS support
set(USE_WINDOWS_SSPI ON) # CURL_USE_SCHANNEL requires CURL_WINDOWS_SSPI set(USE_WINDOWS_SSPI ON) # CURL_USE_SCHANNEL requires CURL_WINDOWS_SSPI
@ -734,7 +737,7 @@ if(CURL_USE_SCHANNEL)
set(_valid_default_ssl_backend TRUE) set(_valid_default_ssl_backend TRUE)
endif() endif()
endif() endif()
if(CURL_WINDOWS_SSPI) if(CURL_WINDOWS_SSPI AND NOT WINDOWS_STORE)
set(USE_WINDOWS_SSPI ON) set(USE_WINDOWS_SSPI ON)
endif() endif()

View File

@ -4351,44 +4351,46 @@ AS_HELP_STRING([--disable-verbose],[Disable verbose strings]),
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
) )
dnl ************************************************************ if test "$curl_cv_winuwp" != 'yes'; then
dnl enable SSPI support dnl ************************************************************
dnl dnl enable SSPI support
AC_MSG_CHECKING([whether to enable SSPI support (Windows native builds only)]) dnl
AC_ARG_ENABLE(sspi, AC_MSG_CHECKING([whether to enable SSPI support (Windows native builds only)])
AS_HELP_STRING([--enable-sspi],[Enable SSPI]) AC_ARG_ENABLE(sspi,
AS_HELP_STRING([--disable-sspi],[Disable SSPI]), AS_HELP_STRING([--enable-sspi],[Enable SSPI])
[ case "$enableval" in AS_HELP_STRING([--disable-sspi],[Disable SSPI]),
yes) [ case "$enableval" in
if test "$curl_cv_native_windows" = "yes"; then yes)
AC_MSG_RESULT(yes) if test "$curl_cv_native_windows" = "yes"; then
AC_DEFINE(USE_WINDOWS_SSPI, 1, [to enable SSPI support]) AC_MSG_RESULT(yes)
USE_WINDOWS_SSPI=1 AC_DEFINE(USE_WINDOWS_SSPI, 1, [to enable SSPI support])
curl_sspi_msg="enabled" USE_WINDOWS_SSPI=1
else curl_sspi_msg="enabled"
AC_MSG_RESULT(no) else
AC_MSG_WARN([--enable-sspi Ignored. Only supported on native Windows builds.]) AC_MSG_RESULT(no)
fi 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 if test "x$SCHANNEL_ENABLED" = "x1"; then
AC_MSG_RESULT(yes) # --with-schannel implies --enable-sspi
else AC_MSG_RESULT(yes)
AC_MSG_RESULT(no) else
fi AC_MSG_RESULT(no)
;; fi
esac ], ;;
if test "x$SCHANNEL_ENABLED" = "x1"; then esac ],
# --with-schannel implies --enable-sspi if test "x$SCHANNEL_ENABLED" = "x1"; then
AC_MSG_RESULT(yes) # --with-schannel implies --enable-sspi
else AC_MSG_RESULT(yes)
AC_MSG_RESULT(no) else
fi AC_MSG_RESULT(no)
) fi
)
if test "x$USE_WINDOWS_SSPI" = "x1"; then if test "x$USE_WINDOWS_SSPI" = "x1"; then
LIBS="-lsecur32 $LIBS" LIBS="-lsecur32 $LIBS"
fi
fi fi
dnl ************************************************************ dnl ************************************************************

View File

@ -130,6 +130,9 @@
#define CERT_FIND_HAS_PRIVATE_KEY (21 << CERT_COMPARE_SHIFT) #define CERT_FIND_HAS_PRIVATE_KEY (21 << CERT_COMPARE_SHIFT)
#endif #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 /* ALPN requires version 8.1 of the Windows SDK, which was
shipped with Visual Studio 2013, aka _MSC_VER 1800: shipped with Visual Studio 2013, aka _MSC_VER 1800:
https://technet.microsoft.com/en-us/library/hh831771%28v=ws.11%29.aspx https://technet.microsoft.com/en-us/library/hh831771%28v=ws.11%29.aspx
@ -377,8 +380,7 @@ set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers,
return CURLE_OK; return CURLE_OK;
} }
#ifdef HAS_CLIENT_CERT_PATH #ifndef UNDER_CE
/* Function allocates memory for store_path only if CURLE_OK is returned */ /* Function allocates memory for store_path only if CURLE_OK is returned */
static CURLcode static CURLcode
get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
@ -444,10 +446,8 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); 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); struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
#ifdef HAS_CLIENT_CERT_PATH
PCCERT_CONTEXT client_certs[1] = { NULL }; PCCERT_CONTEXT client_certs[1] = { NULL };
HCERTSTORE client_cert_store = NULL; HCERTSTORE client_cert_store = NULL;
#endif
SECURITY_STATUS sspi_status = SEC_E_OK; SECURITY_STATUS sspi_status = SEC_E_OK;
CURLcode result; CURLcode result;
@ -461,11 +461,9 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
DEBUGASSERT(backend); DEBUGASSERT(backend);
if(conn_config->verifypeer) { if(conn_config->verifypeer) {
#ifdef HAS_MANUAL_VERIFY_API
if(backend->use_manual_cred_validation) if(backend->use_manual_cred_validation)
flags = SCH_CRED_MANUAL_CRED_VALIDATION; flags = SCH_CRED_MANUAL_CRED_VALIDATION;
else else
#endif
flags = SCH_CRED_AUTO_CRED_VALIDATION; flags = SCH_CRED_AUTO_CRED_VALIDATION;
if(ssl_config->no_revoke) { if(ssl_config->no_revoke) {
@ -533,7 +531,7 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
return CURLE_SSL_CONNECT_ERROR; return CURLE_SSL_CONNECT_ERROR;
} }
#ifdef HAS_CLIENT_CERT_PATH #ifndef UNDER_CE
/* client certificate */ /* client certificate */
if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) {
DWORD cert_store_name = 0; DWORD cert_store_name = 0;
@ -737,11 +735,6 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
} }
client_cert_store = cert_store; 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 #endif
/* allocate memory for the reusable credential handle */ /* allocate memory for the reusable credential handle */
@ -750,23 +743,19 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
if(!backend->cred) { if(!backend->cred) {
failf(data, "schannel: unable to allocate memory"); failf(data, "schannel: unable to allocate memory");
#ifdef HAS_CLIENT_CERT_PATH
if(client_certs[0]) if(client_certs[0])
CertFreeCertificateContext(client_certs[0]); CertFreeCertificateContext(client_certs[0]);
if(client_cert_store) if(client_cert_store)
CertCloseStore(client_cert_store, 0); CertCloseStore(client_cert_store, 0);
#endif
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
backend->cred->refcount = 1; backend->cred->refcount = 1;
#ifdef HAS_CLIENT_CERT_PATH
/* Since we did not persist the key, we need to extend the store's /* Since we did not persist the key, we need to extend the store's
* lifetime until the end of the connection * lifetime until the end of the connection
*/ */
backend->cred->client_cert_store = client_cert_store; backend->cred->client_cert_store = client_cert_store;
#endif
/* We support TLS 1.3 starting in Windows 10 version 1809 (OS build 17763) as /* 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 long as the user did not set a legacy algorithm list
@ -792,12 +781,10 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
credentials.pTlsParameters->grbitDisabledProtocols = credentials.pTlsParameters->grbitDisabledProtocols =
(DWORD)~enabled_protocols; (DWORD)~enabled_protocols;
#ifdef HAS_CLIENT_CERT_PATH
if(client_certs[0]) { if(client_certs[0]) {
credentials.cCreds = 1; credentials.cCreds = 1;
credentials.paCred = client_certs; credentials.paCred = client_certs;
} }
#endif
sspi_status = sspi_status =
Curl_pSecFn->AcquireCredentialsHandle(NULL, Curl_pSecFn->AcquireCredentialsHandle(NULL,
@ -833,12 +820,10 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
schannel_cred.dwFlags = flags | SCH_USE_STRONG_CRYPTO; schannel_cred.dwFlags = flags | SCH_USE_STRONG_CRYPTO;
} }
#ifdef HAS_CLIENT_CERT_PATH
if(client_certs[0]) { if(client_certs[0]) {
schannel_cred.cCreds = 1; schannel_cred.cCreds = 1;
schannel_cred.paCred = client_certs; schannel_cred.paCred = client_certs;
} }
#endif
sspi_status = sspi_status =
Curl_pSecFn->AcquireCredentialsHandle(NULL, Curl_pSecFn->AcquireCredentialsHandle(NULL,
@ -849,10 +834,8 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
&backend->cred->time_stamp); &backend->cred->time_stamp);
} }
#ifdef HAS_CLIENT_CERT_PATH
if(client_certs[0]) if(client_certs[0])
CertFreeCertificateContext(client_certs[0]); CertFreeCertificateContext(client_certs[0]);
#endif
if(sspi_status != SEC_E_OK) { if(sspi_status != SEC_E_OK) {
char buffer[STRERROR_LEN]; char buffer[STRERROR_LEN];
@ -916,15 +899,10 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
#endif #endif
#ifdef UNDER_CE #ifdef UNDER_CE
#ifdef HAS_MANUAL_VERIFY_API
/* certificate validation on Windows CE does not seem to work right; we will /* certificate validation on Windows CE does not seem to work right; we will
* do it following a more manual process. */ * do it following a more manual process. */
backend->use_manual_cred_validation = TRUE; backend->use_manual_cred_validation = TRUE;
#else #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(conn_config->CAfile || conn_config->ca_info_blob) {
if(curlx_verify_windows_version(6, 1, 0, PLATFORM_WINNT, if(curlx_verify_windows_version(6, 1, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) { VERSION_GREATER_THAN_EQUAL)) {
@ -938,12 +916,6 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
} }
else else
backend->use_manual_cred_validation = FALSE; 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 #endif
backend->cred = NULL; backend->cred = NULL;
@ -1087,17 +1059,17 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
failf(data, "schannel: SNI or certificate check failed: %s", failf(data, "schannel: SNI or certificate check failed: %s",
Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
return CURLE_PEER_FAILED_VERIFICATION; return CURLE_PEER_FAILED_VERIFICATION;
/* #if 0
case SEC_E_INVALID_HANDLE: case SEC_E_INVALID_HANDLE:
case SEC_E_INVALID_TOKEN: case SEC_E_INVALID_TOKEN:
case SEC_E_LOGON_DENIED: case SEC_E_LOGON_DENIED:
case SEC_E_TARGET_UNKNOWN: case SEC_E_TARGET_UNKNOWN:
case SEC_E_NO_AUTHENTICATING_AUTHORITY: case SEC_E_NO_AUTHENTICATING_AUTHORITY:
case SEC_E_INTERNAL_ERROR: case SEC_E_INTERNAL_ERROR:
case SEC_E_NO_CREDENTIALS: case SEC_E_NO_CREDENTIALS:
case SEC_E_UNSUPPORTED_FUNCTION: case SEC_E_UNSUPPORTED_FUNCTION:
case SEC_E_APPLICATION_PROTOCOL_MISMATCH: case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
*/ #endif
default: default:
failf(data, "schannel: initial InitializeSecurityContext failed: %s", failf(data, "schannel: initial InitializeSecurityContext failed: %s",
Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
@ -1407,12 +1379,10 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
} }
} }
#ifdef HAS_MANUAL_VERIFY_API
if(conn_config->verifypeer && backend->use_manual_cred_validation) { if(conn_config->verifypeer && backend->use_manual_cred_validation) {
/* Certificate verification also verifies the hostname if verifyhost */ /* Certificate verification also verifies the hostname if verifyhost */
return Curl_verify_certificate(cf, data); return Curl_verify_certificate(cf, data);
} }
#endif
/* Verify the hostname manually when certificate verification is disabled, /* Verify the hostname manually when certificate verification is disabled,
because in that case Schannel will not verify it. */ because in that case Schannel will not verify it. */
@ -1507,12 +1477,10 @@ static void schannel_session_free(void *sessionid)
if(cred->refcount == 0) { if(cred->refcount == 0) {
Curl_pSecFn->FreeCredentialsHandle(&cred->cred_handle); Curl_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
curlx_unicodefree(cred->sni_hostname); curlx_unicodefree(cred->sni_hostname);
#ifdef HAS_CLIENT_CERT_PATH
if(cred->client_cert_store) { if(cred->client_cert_store) {
CertCloseStore(cred->client_cert_store, 0); CertCloseStore(cred->client_cert_store, 0);
cred->client_cert_store = NULL; cred->client_cert_store = NULL;
} }
#endif
Curl_safefree(cred); Curl_safefree(cred);
} }
} }
@ -2359,26 +2327,16 @@ static void schannel_close(struct Curl_cfilter *cf, struct Curl_easy *data)
static int schannel_init(void) static int schannel_init(void)
{ {
#if defined(HAS_ALPN_SCHANNEL) && !defined(UNDER_CE) #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); 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 = WINE_GET_VERSION_FN p_wine_get_version =
CURLX_FUNCTION_CAST(WINE_GET_VERSION_FN, CURLX_FUNCTION_CAST(WINE_GET_VERSION_FN,
(GetProcAddress(GetModuleHandleA("ntdll"), (GetProcAddress(GetModuleHandleA("ntdll"),
"wine_get_version"))); "wine_get_version")));
wine = !!p_wine_get_version; if(p_wine_get_version) { /* WINE detected */
if(wine) {
const char *wine_version = p_wine_get_version(); /* e.g. "6.0.2" */ const char *wine_version = p_wine_get_version(); /* e.g. "6.0.2" */
/* Assume ALPN support with WINE 6.0 or upper */ /* 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 { else {
/* ALPN is supported on Windows 8.1 / Server 2012 R2 and above. */ /* 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, s_win_has_alpn = curlx_verify_windows_version(6, 3, 0, PLATFORM_WINNT,
@ -2483,13 +2441,6 @@ static void schannel_checksum(const unsigned char *input,
DWORD provType, DWORD provType,
const unsigned int algId) const unsigned int algId)
{ {
#ifdef CURL_WINDOWS_UWP
(void)input;
(void)inputlen;
(void)provType;
(void)algId;
memset(checksum, 0, checksumlen);
#else
HCRYPTPROV hProv = 0; HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0; HCRYPTHASH hHash = 0;
DWORD cbHashSize = 0; DWORD cbHashSize = 0;
@ -2535,7 +2486,6 @@ static void schannel_checksum(const unsigned char *input,
if(hProv) if(hProv)
CryptReleaseContext(hProv, 0); CryptReleaseContext(hProv, 0);
#endif
} }
static CURLcode schannel_sha256sum(const unsigned char *input, static CURLcode schannel_sha256sum(const unsigned char *input,
@ -2705,12 +2655,8 @@ const struct Curl_ssl Curl_ssl_schannel = {
{ CURLSSLBACKEND_SCHANNEL, "schannel" }, /* info */ { CURLSSLBACKEND_SCHANNEL, "schannel" }, /* info */
SSLSUPP_CERTINFO | SSLSUPP_CERTINFO |
#ifdef HAS_MANUAL_VERIFY_API
SSLSUPP_CAINFO_BLOB | SSLSUPP_CAINFO_BLOB |
#endif
#ifndef CURL_WINDOWS_UWP
SSLSUPP_PINNEDPUBKEY | SSLSUPP_PINNEDPUBKEY |
#endif
SSLSUPP_CA_CACHE | SSLSUPP_CA_CACHE |
SSLSUPP_HTTPS_PROXY | SSLSUPP_HTTPS_PROXY |
SSLSUPP_CIPHER_LIST, SSLSUPP_CIPHER_LIST,

View File

@ -30,16 +30,6 @@
#include "vtls.h" #include "vtls.h"
#ifndef CURL_WINDOWS_UWP
#define HAS_MANUAL_VERIFY_API
#endif
/* These two macros are missing from mingw-w64 in UWP mode as of v13 */
#if defined(CryptStringToBinary) && defined(CRYPT_STRING_HEX) && \
!defined(DISABLE_SCHANNEL_CLIENT_CERT)
#define HAS_CLIENT_CERT_PATH
#endif
#if defined(_MSC_VER) && (_MSC_VER <= 1600) #if defined(_MSC_VER) && (_MSC_VER <= 1600)
/* Workaround for warning: /* Workaround for warning:
'type cast' : conversion from 'int' to 'LPCSTR' of greater size */ 'type cast' : conversion from 'int' to 'LPCSTR' of greater size */
@ -111,9 +101,7 @@ struct Curl_schannel_cred {
CredHandle cred_handle; CredHandle cred_handle;
TimeStamp time_stamp; TimeStamp time_stamp;
TCHAR *sni_hostname; TCHAR *sni_hostname;
#ifdef HAS_CLIENT_CERT_PATH
HCERTSTORE client_cert_store; HCERTSTORE client_cert_store;
#endif
int refcount; int refcount;
}; };
@ -139,16 +127,11 @@ struct schannel_ssl_backend_data {
BIT(recv_connection_closed); /* true if connection closed, regardless how */ BIT(recv_connection_closed); /* true if connection closed, regardless how */
BIT(recv_renegotiating); /* true if recv is doing renegotiation */ BIT(recv_renegotiating); /* true if recv is doing renegotiation */
BIT(use_alpn); /* true if ALPN is used for this connection */ BIT(use_alpn); /* true if ALPN is used for this connection */
#ifdef HAS_MANUAL_VERIFY_API
BIT(use_manual_cred_validation); /* true if manual cred validation is used */ BIT(use_manual_cred_validation); /* true if manual cred validation is used */
#endif
BIT(sent_shutdown); BIT(sent_shutdown);
BIT(encdata_is_incomplete); BIT(encdata_is_incomplete);
}; };
/* key to use at `multi->proto_hash` */
#define MPROTO_SCHANNEL_CERT_SHARE_KEY "tls:schannel:cert:share"
struct schannel_cert_share { struct schannel_cert_share {
unsigned char CAinfo_blob_digest[CURL_SHA256_DIGEST_LENGTH]; unsigned char CAinfo_blob_digest[CURL_SHA256_DIGEST_LENGTH];
size_t CAinfo_blob_size; /* CA info blob size */ size_t CAinfo_blob_size; /* CA info blob size */

View File

@ -56,8 +56,6 @@
#define BACKEND ((struct schannel_ssl_backend_data *)connssl->backend) #define BACKEND ((struct schannel_ssl_backend_data *)connssl->backend)
#ifdef HAS_MANUAL_VERIFY_API
#ifdef __MINGW32CE__ #ifdef __MINGW32CE__
#define CERT_QUERY_OBJECT_BLOB 0x00000002 #define CERT_QUERY_OBJECT_BLOB 0x00000002
#define CERT_QUERY_CONTENT_CERT 1 #define CERT_QUERY_CONTENT_CERT 1
@ -370,11 +368,7 @@ cleanup:
return result; return result;
} }
#endif
#endif /* HAS_MANUAL_VERIFY_API */
#ifndef UNDER_CE
/* /*
* Returns the number of characters necessary to populate all the host_names. * Returns the number of characters necessary to populate all the host_names.
* If host_names is not NULL, populate it with all the hostnames. Each string * If host_names is not NULL, populate it with all the hostnames. Each string
@ -390,14 +384,6 @@ static DWORD cert_get_name_string(struct Curl_easy *data,
BOOL Win8_compat) BOOL Win8_compat)
{ {
DWORD actual_length = 0; DWORD actual_length = 0;
#ifdef CURL_WINDOWS_UWP
(void)data;
(void)cert_context;
(void)host_names;
(void)length;
(void)alt_name_info;
(void)Win8_compat;
#else
BOOL compute_content = FALSE; BOOL compute_content = FALSE;
LPTSTR current_pos = NULL; LPTSTR current_pos = NULL;
DWORD i; DWORD i;
@ -471,7 +457,6 @@ static DWORD cert_get_name_string(struct Curl_easy *data,
/* Last string has double null-terminator. */ /* Last string has double null-terminator. */
*current_pos = '\0'; *current_pos = '\0';
} }
#endif
return actual_length; return actual_length;
} }
@ -510,12 +495,6 @@ static bool get_alt_name_info(struct Curl_easy *data,
LPDWORD alt_name_info_size) LPDWORD alt_name_info_size)
{ {
bool result = FALSE; bool result = FALSE;
#ifdef CURL_WINDOWS_UWP
(void)data;
(void)ctx;
(void)alt_name_info;
(void)alt_name_info_size;
#else
PCERT_INFO cert_info = NULL; PCERT_INFO cert_info = NULL;
PCERT_EXTENSION extension = NULL; PCERT_EXTENSION extension = NULL;
CRYPT_DECODE_PARA decode_para = { sizeof(CRYPT_DECODE_PARA), NULL, NULL }; CRYPT_DECODE_PARA decode_para = { sizeof(CRYPT_DECODE_PARA), NULL, NULL };
@ -553,7 +532,6 @@ static bool get_alt_name_info(struct Curl_easy *data,
return result; return result;
} }
result = TRUE; result = TRUE;
#endif
return result; return result;
} }
#endif /* !UNDER_CE */ #endif /* !UNDER_CE */
@ -767,7 +745,6 @@ cleanup:
return result; return result;
} }
#ifdef HAS_MANUAL_VERIFY_API
/* Verify the server's certificate and hostname */ /* Verify the server's certificate and hostname */
CURLcode Curl_verify_certificate(struct Curl_cfilter *cf, CURLcode Curl_verify_certificate(struct Curl_cfilter *cf,
struct Curl_easy *data) struct Curl_easy *data)
@ -979,5 +956,4 @@ CURLcode Curl_verify_certificate(struct Curl_cfilter *cf,
return result; return result;
} }
#endif /* HAS_MANUAL_VERIFY_API */
#endif /* USE_SCHANNEL */ #endif /* USE_SCHANNEL */

View File

@ -28,6 +28,9 @@ if test "x$OPT_SCHANNEL" != xno; then
ssl_msg= ssl_msg=
if test "x$OPT_SCHANNEL" != "xno" && if test "x$OPT_SCHANNEL" != "xno" &&
test "x$curl_cv_native_windows" = "xyes"; then test "x$curl_cv_native_windows" = "xyes"; then
if test "$curl_cv_winuwp" = 'yes'; then
AC_MSG_ERROR([UWP does not support Schannel.])
fi
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
AC_DEFINE(USE_SCHANNEL, 1, [to enable Windows native SSL/TLS support]) AC_DEFINE(USE_SCHANNEL, 1, [to enable Windows native SSL/TLS support])
ssl_msg="Schannel" ssl_msg="Schannel"