My company was recently surprised by the expiration of a code signing certificate and had to scramble to find a replacement certificate, only to discover that the landscape of code signing has shifted as of last year to a USB-key based system where certificates are no longer generally accessible directly. Looking into alternatives, we settled on the new Azure Trusted Signing service that offers a kind of ‘signing as-a-service’ experience, and we were able to jury-rig our build process to use it well enough in a Windows context. We now want to properly incorporate it into our modern CI/CD pipeline, but we made the shift into Linux build-time and runtime a few years ago, and it appears that there is no obvious way to invoke Azure Trusted Signing from a Linux runtime.
The primary supported way (according to the documentation here https://learn.microsoft.com/en-us/azure/trusted-signing/how-to-signing-integrations) appears to be to use a special version of signtool.exe that seems to side-load a separate MS library that makes a web request to the signing resource in Azure. This is what I previously got working, and it appears to be what’s hidden underneath all of the alternatives listed (github/Azure Devops action, powershell, sdk), but all of those seem to be brand new and have no documentation/instructions and nobody asking about them yet, and none work outside of a Windows context.
I have tried using Wine 9 to invoke my working signtool.exe setup from an Ubuntu 20.04 context with a clean installation, but I receive an error that I cannot figure out how to resolve:
wine "./Microsoft.Windows.SDK.BuildTools_10.0.22621.0/signtool.exe" sign /debug /v /fd SHA256 /tr "http://timestamp.acs.microsoft.com" /td SHA256 /dlib "./Microsoft.Trusted.Signing.Client_1.0.53/Azure.CodeSigning.Dlib.dll" /dmdf "./signinfo.json" "/home/asdf.exe"
007c:fixme:hid:handle_IRP_MN_QUERY_ID Unhandled type 00000005
007c:fixme:hid:handle_IRP_MN_QUERY_ID Unhandled type 00000005
007c:fixme:hid:handle_IRP_MN_QUERY_ID Unhandled type 00000005
007c:fixme:hid:handle_IRP_MN_QUERY_ID Unhandled type 00000005
00f8:err:module:import_dll Library MFC42.dll (which is needed by L"Z:\home\Microsoft.Windows.SDK.BuildTools_10.0.22621.0\signtool.exe") not found
00f8:err:module:loader_init Importing dlls for L"Z:\home\Microsoft.Windows.SDK.BuildTools_10.0.22621.0\signtool.exe" failed, status c0000135
I have run winetricks mfc42 successfully and have verified that the .dll is in the syswow64 virtual folder, and I have tried moving my folder containing the signtool resources into the virtual program files directory, all to no effect. The version of signtool.exe I’m invoking is 64 bit, and I verified that my wine installation is working by running wine notepad.exe with no issue.
As a workaround, I’m currently working on an Azure function that my build can invoke when it’s time to sign .exes (all so that I can be in a Windows context), but this represents a huge security risk, as I’m essentially just making a URL that anyone behind my firewall can hit to sign anything they want.
Why does using wine to run signtool.exe not work? Is there a better way to accomplish what I’m trying to do, assuming that I do not want to switch to another code signing provider and want to continue to use Azure Trusted Signing?
2
Answers
Azure Trusted Signing is supported by Jsign, a cross-platform open-source alternative to signtool.exe. Wine is not required. The syntax looks like this:
Azure Trusted Signing support will be part of the upcoming 7.0 release. In the meantime you’ll have to build the project yourself (with
mvn package -DskipTests
) or download the latest CI artifacts from the GitHub Actions.(Disclaimer: I’m the author of this project)
Could you please tell me in a bit more detail how you managed to get this to work? I get a response from Jsign saying "Adding Authenticode signature to "EXE" " But it doesnt seem like it actually signs the executable.