sign icon indicating copy to clipboard operation
sign copied to clipboard

Signing failed with error -2147012744.

Open janstaelensskyline opened this issue 1 year ago • 3 comments

Describe the Bug

Environments:

  • Windows Server 2019 Standard 64-bit (10.0, Build 17763) (17763.rs5_release.180914-1434)
  • Windows 10 Pro 64-bit (10.0, Build 19045) (19041.vb_release.191206-1406)
  • .NET SDK Version: 8.0.202
  • Tool Version: 0.9.1-beta.24312.3 (same behavior in older versions)

When executing dotnet sign on a .nupkg file using Azure Key Vault, we encounter the following error:

Signing failed with error -2147012744.
  • Error Code: Hex: 0x80072EE8
  • Commandline output: Even when running as an administrator.
  • MSTest integration test that executes the dotnet.exe process with signing also fails.

Interestingly, this issue does not occur when running the code from an Azure Pipeline on a provided Windows machine. It suggests we might be missing a prerequisite on our personal computers. It does happen on our Jenkins setup running on the above specified windows 2019 server.

After some investigation, it appears the error originates from deep within the code, specifically from calls to the Windows OS to sign the assemblies inside the .nupkg.

// Example of the error code
logger?.LogTrace("Calling SignerSignEx3");
var result = mssign32.SignerSignEx3;

// Signing code snippet
try
{
    using (var ctx = new Kernel32.ActivationContext(manifestFile))
    {
        code = signer.SignFile(
            file.FullName,
            options.Description,
            options.DescriptionUrl?.AbsoluteUri,
            pageHashing: null,
            _logger);
        success = code == S_OK;
    }
}
catch (Exception e)
{
    _logger.LogError(e, e.Message);
}

if (success)
{
    _logger.LogInformation(Resources.SigningSucceeded, file.FullName);
    return true;
}

_logger.LogError(Resources.SigningFailedWithError, code);

The problem is that I'm not familiar enough with the SignerSignEx3 WinAPI call and it seems like documentation will be private to Microsoft. At this point, it's likely that I've gone too deep and am missing a more obvious issue.

Repro Steps

  1. Create a .nupkg that includes .net462 assemblies.
  2. Execute the following C# code (assuming dotnet is a class that starts dotnet.exe as a process with the provided string as an argument):
dotnet.Run("new tool-manifest");
dotnet.Run("tool install sign --version 0.9.1-beta.24312.3");

string command = $"sign code azure-key-vault \"{packageAbsolutePath}\" " +
"--publisher-name \"Fake Company\" " +
"--description \"Fake Signing\" " +
"--description-url \"https://www.fakecompany.be/\" " +
"--azure-key-vault-tenant-id \"123-fake-id\" " +
"--azure-key-vault-client-id \"123-fake-id\" " +
$"--azure-key-vault-client-secret \"{nugetStore.NuGetCertificatePassword}\" " +
"--azure-key-vault-certificate \"CompanyDefault\" " +
"--azure-key-vault-url \"https://common-certificates.vault.azure.net/\" " +
$"--output \"{resultDirectory}\"";

dotnet.Run(command);

Expected Behavior

Expecting to see a signed .nupkg with all content signed.

Actual Behavior

Signing starts, then it retries over and over again until it throws an exception.

Standard Output:

Tool 'sign' is up to date (version '0.9.1-beta.24312.3' manifest file C:\GIT\Solutions\Internal\CICD\SysDev\NuGetSigningIntegrationTests\bin\Debug\.config\dotnet-tools.json).
fail: Sign.Core.ISignatureProvider[0]
      Signing failed with error -2147012744.
      (repeats multiple times)
fail: Sign.Core.ISignatureProvider[0]
      Failed to sign. Attempts exceeded.
fail: Sign.Core.ISigner[0]
      Could not sign C:\Users\JANS\AppData\Local\Temp\dno54dl1.xna\lib\Newtonsoft.Json.dll.
      System.Exception: Could not sign C:\Users\JANS\AppData\Local\Temp\dno54dl1.xna\lib\Newtonsoft.Json.dll.
         at Sign.Core.AzureSignToolSignatureProvider.<>c__DisplayClass7_0.<<SignAsync>b__0>d.MoveNext() in /_/src/Sign.Core/SignatureProviders/AzureSignToolSignatureProvider.cs:line 110
      --- End of stack trace from previous location ---
         at System.Threading.Tasks.Parallel.<>c__53`1.<<ForEachAsync>b__53_0>d.MoveNext()
      --- End of stack trace from previous location ---
         at Sign.Core.AzureSignToolSignatureProvider.SignAsync(IEnumerable`1 files, SignOptions options) in /_/src/Sign.Core/SignatureProviders/AzureSignToolSignatureProvider.cs:line 104
         at Sign.Core.AggregatingSignatureProvider.SignAsync(IEnumerable`1 files, SignOptions options) in /_/src/Sign.Core/SignatureProviders/AggregatingSignatureProvider.cs:line 204
         at Sign.Core.AggregatingSignatureProvider.SignAsync(IEnumerable`1 files, SignOptions options) in /_/src/Sign.Core/SignatureProviders/AggregatingSignatureProvider.cs:line 92
         at Sign.Core.Signer.<>c__DisplayClass3_0.<<SignAsync>b__0>d.MoveNext() in /_/src/Sign.Core/Signer.cs:line 156
      --- End of stack trace from previous location ---
         at System.Threading.Tasks.Parallel.<>c__53`1.<<ForEachAsync>b__53_0>d.MoveNext()
      --- End of stack trace from previous location ---
         at Sign.Core.Signer.SignAsync(IReadOnlyList`1 inputFiles, String outputFile, FileInfo fileList, DirectoryInfo baseDirectory, String applicationName, String publisherName, String description, Uri descriptionUrl, Uri timestampUrl, Int32 maxConcurrency, HashAlgorithmName fileHashAlgorithm, HashAlgorithmName timestampHashAlgorithm) in /_/src/Sign.Core/Signer.cs:line 85

Additional Context

  • Sign Version: 0.9.1-beta.24312.3
  • dotnet info: dotnet --info

.NET SDKs Installed

  • 2.1.526, 2.2.207, 3.1.426, 5.0.408, 5.0.416, 6.0.202, 6.0.203, 6.0.321, 8.0.106, 8.0.202

.NET Runtimes Installed

  • Microsoft.AspNetCore.All 2.1.30, 2.2.8
  • Microsoft.AspNetCore.App 2.1.30, 2.2.8, 3.1.32, 5.0.17, 6.0.5, 6.0.28, 6.0.31, 7.0.17, 8.0.6
  • Microsoft.NETCore.App 2.1.30, 2.2.8, 3.1.32, 5.0.17, 6.0.5, 6.0.28, 6.0.31, 7.0.17, 8.0.6
  • Microsoft.WindowsDesktop.App 3.1.32, 5.0.17, 6.0.5, 6.0.28, 6.0.31, 7.0.17, 8.0.6

Other Architectures Found

  • x86: [C:\Program Files (x86)\dotnet]
    • Registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment Variables

  • Not set

global.json File

  • Not found

Learn More

Download .NET

janstaelensskyline avatar Jun 13 '24 14:06 janstaelensskyline

Hi @janstaelensskyline unfortunately, those versions of Windows are both out of the mainstream support lifecycle, so there's not a lot we can do for those.

That said Sign CLI carries its own copies of the Authenticode signing libraries and that activation context should be forcing the tool to use those versions instead of the ones the OS carries. @dtivel, looks like there may be an issue here? Can we confirm that the correct libraries are being loaded and used at runtime?

clairernovotny avatar Jun 13 '24 21:06 clairernovotny

Hello @clairernovotny , understood. Do you have a list with the mainstream support for what version of windows OS is supported and part of your QA cycle for the signing of .nupkg?

janstaelensskyline avatar Jun 17 '24 08:06 janstaelensskyline

Update on this issue. I've continued debugging this on my end. It's been strange... I tested running the AzureSign Tool on an assembly and the KeyVaultSign tool on a .nupkg directly with our same azure keyvault settings and both those tools worked on every PC and Server. Only the sign tool itself kept failing.

Up to an including 19/06/2024

Using the exact same sign command as mentioned in the first post, version of the tool and the same .nupkg package. All the servers & pc's have .NET8 installed.

On azure pipelines using windows host: WORKS On Github pipelines using windows host: WORKS

On 2 Pc's with Windows 10: FAILS WITH ERROR -2147012744

On 1 PC with Windows 11: FAILS WITH ERROR -2147012744

On Windows Server 2019: FAILS WITH ERROR -2147012744

On Windows Server 2022: FAILS WITH ERROR -2146762749

Today on 20/06/2024

the command suddenly started working on 2 PC's with Windows 10: 1 PC with Windows 11:

Both the servers are still failing (2019 and 2022) but with different error codes.

what changed

I spend a while checking to see what 'changed' on the PC's that didn't on the servers but I'm not finding much. I saw a windows update for microsoft defender: KB2267602. But when I installed that on the server nothing changed. There was no reboot or restart for one of the win10 pc's for over 7 days so I'm not immediately seeing other windows updates being a factor there.

On applications I didn't see any updates that every PC had and that the servers might've been missing.

current status

Currently I'm not able to really figure this out. I'll setup our self-hosted jenkins pipelines to use the NuGetKeyVault tool directly for now, but we'd prefer to use the same dotnet sign tool on all our CI/CD.

janstaelensskyline avatar Jun 20 '24 12:06 janstaelensskyline

I think I had the same problem and in my case, installation of "Microsoft Visual C++ 14 runtime" (https://aka.ms/vs/17/release/vc_redist.x64.exe) helped. It's required component, described in readme (https://github.com/dotnet/sign?tab=readme-ov-file).

Azure Pipelines agents have some preinstalled components, that's why there signing worked.

pwx24 avatar Sep 25 '24 13:09 pwx24

@janstaelensskyline, see https://github.com/dotnet/sign?tab=readme-ov-file#prerequisites . I've updated that section since this issue was opened.

If you try using the latest Sign CLI, it will raise a warning if the Microsoft Visual C++ 14 runtime" is not already installed.

dtivel avatar Oct 07 '24 18:10 dtivel

Test Results for Latest .NET Sign (Version 0.9.0-beta.24469.1)

That's excellent news indeed. I've tested the latest dotnet sign version 0.9.0-beta.24469.1:

Windows 10

  • .nupkg: OK
  • .dll: OK

Windows 11

  • .nupkg: OK
  • .dll: OK

Windows Server 2019

  • .nupkg: OK
  • .dll: OK

Windows Server 2022

  • .nupkg: OK
  • .dll: OK

Thank you for the follow-up and fixes. We'll start/continue using the pre-release in our environments and will notify you if we see anything out of the ordinary.

janstaelensskyline avatar Oct 08 '24 06:10 janstaelensskyline