3.8 KiB
Wine SDK certificate trust
scripts/wine-sdk-trust.cs is a .NET 10 file-based helper for validating the public root-certificate bundles distributed with the Microsoft SDK and importing them into a disposable Wine prefix's Windows CurrentUser Root store. It does not disable NuGet signature verification or certificate checks and does not import private keys.
dotnet publish scripts/wine-sdk-trust.cs -c Release -p:UseAppHost=false -p:PublishAot=false -o artifacts/wine-sdk-trust
dotnet artifacts/wine-sdk-trust/WineSdkTrust.dll --validate /path/to/sdk/trustedroots/codesignctl.pem /path/to/sdk/trustedroots/timestampctl.pem
Validation is read-only on every OS. Both files must exist and contain public PEM certificates. Explicit non-CA certificates are rejected. Historical self-issued SDK roots without BasicConstraints remain valid; certificate expiry is not filtered because trusted bundles also support historical signatures. The helper logs each bundle's certificate count and SHA-256, then the unique certificate count. Use bundles from the verified Microsoft SDK archive and retain those hashes with the SDK provenance.
For the Windows SDK installed inside a disposable Wine prefix, invoke the published DLL with --import and the two authoritative Linux SDK bundle paths, for example:
"${WINE_BIN}" "${WIN_DOTNET_DIR}/dotnet.exe" artifacts/wine-sdk-trust/WineSdkTrust.dll --import \
"Z:${DOTNET_ROOT}/sdk/10.0.401/trustedroots/codesignctl.pem" \
"Z:${DOTNET_ROOT}/sdk/10.0.401/trustedroots/timestampctl.pem"
The import mode first requires OperatingSystem.IsWindows() and the Wine-specific wine_get_version export from ntdll.dll, located with NativeLibrary.TryLoad and TryGetExport. Native Windows is rejected as well as macOS/Linux. Only after both bundles validate does it open CurrentUser Root for writing and call AddRange. It closes the store, reopens it read-only and asserts that every imported thumbprint is present. There is no localized shell command, interactive prompt or GUI automation. Missing/unknown arguments and import attempts outside Wine return 2; validation/import failures return 1; successful validation or verified import returns 0.
The write side effect is confined to the selected Wine prefix's current-user root store. Repeated imports are safe. Run it only against the disposable CI prefix. Native validation never opens any certificate store, and native import attempts are rejected before parsing bundles or constructing a store. The normal PR workflow publishes this DLL and imports the bundles before the Windows desktop restore/build. This repair still requires a real Wine restore/build result to establish that it fixes the observed trust failure.
Microsoft documents that these SDK bundles originate from its Trusted Root Program and provide code-signing and timestamping roots. The Windows NuGet restore remains responsible for checking actual package signatures; this helper populates the Wine store used for those checks.
Local qualification on 2026-10-03 used SDK 10.0.203 to publish the DLL and the authoritative bundles from SDK 10.0.401 to validate it on macOS/.NET 10.0.7. Both bundles passed: codesign contained 307 certificates including seven historical roots without constraints; timestamp contained 327 including two such roots; the union contained 372 unique thumbprints. Their SHA-256 hashes were AAB671F52E5229906B2100727370007EF4B6D2E360B23F2CF12A6D87773BE611 and 5CCB03367B52F047099F07E1653160E8578A83711CB18560C979FEBB65F8CB5D, respectively. A native --import invocation with those same paths returned 2 before parsing bundles or opening a store; unknown arguments returned 2, and an empty input returned 1. No local store import was performed. This is helper qualification, not a passing Wine/NuGet result.