dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.71k stars 1.06k forks source link

need a real authenticode build step; msbuild signtool doesn't cut it #26170

Open joshudson opened 2 years ago

joshudson commented 2 years ago

Is your feature request related to a problem? Please describe.

Signing executables at build time works really badly; but MS's own antivirus cares about signed files

Describe the solution you'd like

Implement a dotnet signtool that depends only on the dotnet sdk; should not depend on additional tools being installed

The sign build step has too many restrictions:

Additional context

I would rather not care about signed binaries; but Windows Smart Screen does. You would get a lot more uptake if the infrastructure restrictions weren't so awful.

I made a mistake in my original analysis. I had completely overlooked the baseline requirement for code signing certificates to be in protected hardware modules, and therefore thought the best solution was to reimplement GetDigestStream in C# and use the existing X509 infrastructure for something between 500 and 2000 lines of code depening on how much code it takes to implement timestamping. The hardware certificate changes the game completely and it's now most efficient to shell out on non-windows platforms, and if signtool had an independent installer rather than being tied to the maintenance nightmare that Visual Studio Build tools is, it would be the same on Windows too.

joeloff commented 2 years ago

SignTool depends heavily on the cryptographic APIs in Windows - these APIs do not exist on non-Windows platforms. In case like these you'd either need a Windows based service to which the files can be submitted or rely on a 3rd party service that provides code sign services. If the application/files are intended for wide distribution you'd likely need to have a certificate that's rooted in a trusted certificate authority that users would be able to add to their certificate stores on Windows to verify your certificate.

If you create applications for MacOS, you have to use the codesign tool on MacOS to sign your application if GateKeeper is enabled on the target machine.

KalleOlaviNiemitalo commented 2 years ago

There is "osslsigncode" for making Authenticode signatures using OpenSSL, but its GPLv3 license may make it unsuitable as a dependency of .NET SDK, and I don't know whether it supports private keys stored in a hardware crypto module like Baseline Requirements (Code Signing) will require.

joshudson commented 2 years ago

@KalleOlaviNiemitalo : It's no more than taking a dependency on the native compiler. You just run the binary. The commentary by the GPL authors says that doesn't bind your code to being GPL.

I imagine you could use the following solution to implement the build step:

    if (windows)
    {
        /* call the p/invoke methods to access the windows APIs */
        /* while osslsigncode has trivial install steps; the same is *not* true of signtool.exe */
    } else {
        Process process;
        p.Arguments = "osslsigncode " + //...
        p.Start();
        p.WaitForExit();
    }

For those interested, opensslsigncode does support hardware crypto modules via PKCS11. It says so in its own readme.