Skip to content

schannel: add ALPN support for mingw-w64 <9 and <VS2015 - #22739

Closed
vszakats wants to merge 5 commits into
curl:masterfrom
vszakats:w-try-old-alpn
Closed

vszakats wants to merge 5 commits into
curl:masterfrom
vszakats:w-try-old-alpn

Conversation

@vszakats

@vszakats vszakats commented Aug 29, 2026

Copy link
Copy Markdown
Member

To bring these builds on par with the rest of supported Windows
toolchains.

Also: drop dead MS documentation URL.

@vszakats
vszakats marked this pull request as draft August 29, 2026 10:21
@vszakats vszakats changed the title schannel: try enabling alpn for old toolchains [TEST] schannel: try enabling alpn for old toolchains Aug 29, 2026
@github-actions github-actions Bot added TLS Windows Windows-specific labels Aug 29, 2026
@vszakats vszakats changed the title [TEST] schannel: try enabling alpn for old toolchains schannel: add ALPN support for mingw-w64 <9 and <VS2015 Aug 29, 2026
@vszakats
vszakats marked this pull request as ready for review August 29, 2026 10:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds Schannel ALPN support when building with older mingw-w64 and Microsoft SDK headers.

Changes:

  • Adds missing ALPN declarations for older headers.
  • Enables existing ALPN logic across supported Windows toolchains.
  • Retains runtime OS/Wine capability detection.
File summaries
File Description
lib/vtls/schannel.c Adds compatibility declarations and removes compile-time ALPN gating.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread lib/vtls/schannel.c Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@jay

jay commented Aug 29, 2026

Copy link
Copy Markdown
Member

(something is wonky with the version checks tldr)

I'm seeing some weird behavior with this. I built this branch in VS2010 and then I ran it in Windows 7 (ok - no alpn and no errors) and Windows 11 (not ok - no alpn and no errors). I can't figure out is why it's not showing alpn results in Windows 11. So far I traced it to s_pRtlVerifyVersionInfo being NULL (in this case curl falls back on the regular verify version info which will not return Windows 11 so it thinks there is no ALPN).

But this makes no sense. I put a printf in curlx_verify_windows_version
fprintf(stderr, "schannel: s_pRtlVerifyVersionInfo %p\n", s_pRtlVerifyVersionInfo);

I get weird results where it's valid but then nulled and then valid again which makes no sense

schannel: s_pRtlVerifyVersionInfo 773E7E50
schannel: ZZZZZZZZZZZ matched: 1
schannel: s_pRtlVerifyVersionInfo 773E7E50
schannel: ZZZZZZZZZZZ matched: 1
schannel: YYYYYYYYYYYYYYY s_win_has_alpn: 0
schannel: s_pRtlVerifyVersionInfo 00000000
schannel: YYYYYYYYYYYYYYY s_win_has_alpn: 0
Major Version: 10
Minor Version: 0
Build Number:  22000
* !!! WARNING !!!
* This is a debug build of libcurl, do not use in production.
* Host google.com:443 was resolved.
* IPv6: (none)
* IPv4: 142.250.65.78
*   Trying 142.250.65.78:443...
schannel: s_pRtlVerifyVersionInfo 773E7E50
schannel: ZZZZZZZZZZZ matched: 1
schannel: s_pRtlVerifyVersionInfo 773E7E50
schannel: ZZZZZZZZZZZ matched: 1

I did a "find all references" on s_pRtlVerifyVersionInfo in VS and I can't tell where it's being nulled. Also reproducible in Windows 7. Something is up here I'm not sure it's even related to this branch

https://github.com/vszakats/curl/compare/w-try-old-alpn...jay:curl:w-try-old-alpn_SPRINKLE?expand=1

next I'll try a data breakpoint but out of time for now

@jay

jay commented Aug 29, 2026

Copy link
Copy Markdown
Member

alright I think I'm on to something, i logged curlx_verify_windows_init and and I see it's called twice, but the second time it's called after the null result, which might mean s_pRtlVerifyVersionInfo is used before it's initialized in the library (like there's two of them?), i'll look into it more later

curlx_verify_windows_init s_pRtlVerifyVersionInfo 773E7E50
schannel: s_pRtlVerifyVersionInfo 773E7E50
schannel: ZZZZZZZZZZZ matched: 1
schannel: s_pRtlVerifyVersionInfo 773E7E50
schannel: ZZZZZZZZZZZ matched: 1
schannel: YYYYYYYYYYYYYYY s_win_has_alpn: 0
schannel: s_pRtlVerifyVersionInfo 00000000
schannel: YYYYYYYYYYYYYYY s_win_has_alpn: 0
Major Version: 10
Minor Version: 0
Build Number:  22000
curlx_verify_windows_init s_pRtlVerifyVersionInfo 773E7E50
* !!! WARNING !!!
* This is a debug build of libcurl, do not use in production.

@vszakats

vszakats commented Aug 30, 2026

Copy link
Copy Markdown
Member Author

Just reading the code, the issue may be that Curl_ssl_init() is called before Curl_win32_init(); the former is querying the Windows version (for ALPN initialization), but the function pointer is only initialized in the latter. Also, in shared curl builds, there are two copies of s_pRtlVerifyVersionInfo, which may explain the surprising trace output, and also means this issue is not present in static builds, because main() does the initialization via win32_init().

If this theory holds, this patch may fix it:

--- a/lib/easy.c
+++ b/lib/easy.c
@@ -136,6 +136,11 @@ static CURLcode global_init(long flags, bool memoryfuncs)
     Curl_ccalloc = (curl_calloc_callback)calloc;
   }
 
+  if(Curl_win32_init(flags)) {
+    DEBUGF(curl_mfprintf(stderr, "Error: win32_init failed\n"));
+    goto fail;
+  }
+
   if(Curl_trc_init()) {
     DEBUGF(curl_mfprintf(stderr, "Error: Curl_trc_init failed\n"));
     goto fail;
@@ -151,11 +156,6 @@ static CURLcode global_init(long flags, bool memoryfuncs)
     goto fail;
   }
 
-  if(Curl_win32_init(flags)) {
-    DEBUGF(curl_mfprintf(stderr, "Error: win32_init failed\n"));
-    goto fail;
-  }
-
   if(Curl_amiga_init()) {
     DEBUGF(curl_mfprintf(stderr, "Error: Curl_amiga_init failed\n"));
     goto fail;

@jay jay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VS2010 build of this PR running in Windows 7 and Windows 11 work as expected (no ALPN and ALPN respectively) with your fix from #22746 (I turned your patch into a commit, set you as the author and made it a separate PR)

@vszakats vszakats closed this in a009957 Aug 30, 2026
@vszakats
vszakats deleted the w-try-old-alpn branch August 30, 2026 08:56
vszakats added a commit that referenced this pull request Aug 31, 2026
- In easy.c global_init, initialize win32 before ssl.

Schannel SSL init depends on win32 initialization.

Prior to this change applications with no compatibility manifest using a
libcurl with Schannel had ALPN erroneously disabled. During Schannel
init there is a version info check so that ALPN is only enabled for
Windows 8.1 or later (>= NT 6.3), but since win32 was not yet
initialized the version check would fail even if the OS was more recent.

This change ensures that the pointer to function RtlVerifyVersionInfo is
initialized before SSL initialization so that version checks during SSL
initialization do not use VerifyVersionInfo as a fallback.

On Windows RtlVerifyVersionInfo compares against the actual OS version
info whereas VerifyVersionInfo has behavior that varies depending on
whether the application (eg curl tool) has a compatibility manifest. If
there is no manifest, VerifyVersionInfo treats the OS version to compare
against as Windows 8 (NT 6.2) even on later versions.

So basically NT 6.2 < NT 6.3 caused ALPN to be erroneously disabled.

Reported-by: Jay Satiro

Ref: https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-verifyversioninfoa

Fixes #22739 (comment)

Closes #22746
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

3 participants