Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Azure Trusted Signing APPX release for Microsoft Store not possible #8948

Open
JJ-8 opened this issue Mar 10, 2025 · 10 comments
Open

Bug: Azure Trusted Signing APPX release for Microsoft Store not possible #8948

JJ-8 opened this issue Mar 10, 2025 · 10 comments

Comments

@JJ-8
Copy link

JJ-8 commented Mar 10, 2025

I am using Azure Trusted Signing to sign Windows DLLs/EXEs with electron-builder 26.0.10. This works fine when creating an MSI release. However, I encounter two bugs when creating an appx release:

  1. The win.azureSignOptions.publisherName is used in the <Identity Publisher="..." /> in the AppxManifest.xml. This is confusing since this requires to use the format CN=<company name> while the docs say that win.azureSignOptions.publisherName should only have <company name> matching the certificate.
  2. Since I want to publish the appx to the Microsoft Store, it should not be signed since Microsoft takes care of signing. However, electron-builder still attempts to sign the corresponding appx but it fails. Below you can find the exact output of the sign command:
$ powershell.exe -NoProfile -NonInteractive -Command Invoke-TrustedSigning -Endpoint https://neu.codesigning.azure.net -CertificateProfileName <redacted> -CodeSigningAccountName <redacted> -TimestampRfc3161 http://timestamp.acs.microsoft.com -TimestampDigest SHA256 -FileDigest SHA256 -Files "C:\<redacted>\dist\<redacted>.appx"
imestamp.acs.microsoft.com -TimestampDigest SHA256 -FileDigest SHA256 -Files "C:\\<redacted>\\dist\\<redacted>.appx";f24e1483-a43c-40f0-9cce-b6f27e0ec761Checking for required dependencies.
        Build tools package installed: True
        Trusted signing package installed: True
        Sign CLI package installed: True
        All required dependencies are installed.

Creating metadata file: C:\<redacted>\AppData\Local\TrustedSigning\Microsoft.Trusted.Signing.Client\Microsoft.Trusted.Signing.Client.1.0.53\bin\x64\metadata.json

Getting the list of files to be signed.
        Getting files from list.
        Listed files: 1
                C:\<redacted>\dist\<redacted>.appx

        No files folder was provided.
        Filtered files: 0

        No catalog file was provided.
        Catalog files: 0

Formatting the list of files to be signed.

Batching the list of files to be signed by SignTool.
        Batched SignTool files: 1

Batching the list of files to be signed by SignCli.
        No SignCli files were found to sign.

Signing SignTool file batch 1 of 1.
        Executing signtool.exe: C:\<redacted>\AppData\Local\TrustedSigning\Microsoft.Windows.SDK.BuildTools\Microsoft.Windows.SDK.BuildTools.10.0.22621.3233\bin\10.0.22621.0\x64\signtool.exe sign /v /debug /fd SHA256 /tr http://timestamp.acs.microsoft.com /td SHA256 /dlib "C:\<redacted>\AppData\Local\TrustedSigning\Microsoft.Trusted.Signing.Client\Microsoft.Trusted.Signing.Client.1.0.53\bin\x64\Azure.CodeSigning.Dlib.dll" /dmdf "C:\<redacted>\AppData\Local\TrustedSigning\Microsoft.Trusted.Signing.Client\Microsoft.Trusted.Signing.Client.1.0.53\bin\x64\metadata.json" "C:\<redacted>\dist\<redacted>.appx"

Trusted Signing

Version: 1.0.53

"Metadata": {
  "Endpoint": "https://neu.codesigning.azure.net",
  "CodeSigningAccountName": "<redacted>",
  "CertificateProfileName": "<redacted>",
  "ExcludeCredentials": []
}

Submitting digest for signing...
Unhandled managed exception
Azure.RequestFailedException: Service request failed.
Status: 403 (Forbidden)

Headers:
Date: Mon, 10 Mar 2025 13:24:41 GMT
Connection: keep-alive
Strict-Transport-Security: REDACTED
x-azure-ref: REDACTED
X-Cache: REDACTED
Content-Length: 0

   at Azure.CodeSigning.CertificateProfileRestClient.SignAsync(String codeSigningAccountName, String certificateProfileName, SignRequest body, String xCorrelationId, String clientVersion, CancellationToken cancellationToken)
   at Azure.CodeSigning.CertificateProfileClient.StartSignAsync(String codeSigningAccountName, String certificateProfileName, SignRequest body, String xCorrelationId, String clientVersion, CancellationToken cancellationToken)
   at Azure.CodeSigning.Dlib.Core.DigestSigner.SignAsync(UInt32 algorithm, Byte[] digest, SafeFileHandle safeFileHandle, CancellationToken cancellationToken)
   at Azure.CodeSigning.Dlib.Core.DigestSigner.Sign(UInt32 algorithm, Byte[] digest, SafeFileHandle safeFileHandle)
   at AuthenticodeDigestSignExWithFileHandleManaged(_CRYPTOAPI_BLOB* pMetadataBlob, UInt32 digestAlgId, Byte* pbToBeSignedDigest, UInt32 cbToBeSignedDigest, Void* hFile, _CRYPTOAPI_BLOB* pSignedDigest, _CERT_CONTEXT** ppSignerCert, Void* hCertChainStore)

SignTool Error: An unexpected internal error has occurred.
Error information: "Error: SignerSign() failed." (-2147467259/0x80004005)
SignTool failed with exit code 1
At C:\<redacted>\Documents\WindowsPowerShell\Modules\TrustedSigning\0.5.3\TrustedSigning.psm1:293 char:13
+             throw "SignTool failed with exit code $($result)"
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (SignTool failed with exit code 1:String) [], RuntimeException
    + FullyQualifiedErrorId : SignTool failed with exit code 1

I think the solution for this is to allow exclusion of signing for the appx release? However, I do not want to fully turn off Trusted Signing since the DLLs/EXEs inside the appx should still be signed. Only the final artifact should not be signed.

@mmaietta
Copy link
Collaborator

mmaietta commented Mar 10, 2025

The win.azureSignOptions.publisherName is used in the in the AppxManifest.xml. This is confusing since this requires to use the format CN= while the docs say that win.azureSignOptions.publisherName should only have matching the certificate

Wait, where does it say that? I see: https://www.electron.build/app-builder-lib.interface.windowsazuresigningconfiguration#publishername

exactly as in your code signed certificate

Since I want to publish the appx to the Microsoft Store, it should not be signed since Microsoft takes care of signing. However, electron-builder still attempts to sign the corresponding appx but it fails.
I think the solution for this is to allow exclusion of signing for the appx release? However, I do not want to fully turn off Trusted Signing since the DLLs/EXEs inside the appx should still be signed. Only the final artifact should not be signed.

Just to understand this a bit more, are Appx always supposed to not be signed? Just the dll/exe's within it? Trying to understand if we need a configuration prop for azureSignOptions or if it always is not supposed to get signed by azure.

Based on your logs, it looks like you're receiving a 403 though, can you check your configuration + token?

Unhandled managed exception
Azure.RequestFailedException: Service request failed.
Status: 403 (Forbidden)

@JJ-8
Copy link
Author

JJ-8 commented Mar 11, 2025

@mmaietta thank you for looking into this issue!

Wait, where does it say that? I see: https://www.electron.build/app-builder-lib.interface.windowsazuresigningconfiguration#publishername

Yes exactly, I interpreted this to input only "<company name>" into this option. And this works fine for non-appx builds (MSI for example). But for appx I had to change this to "CN=<company name>" since otherwise the XML is invalid. However, using the "CN=<company name>" format does not break the other signing methods. But perhaps this was only a confusion at my end? Still weird that it also accepts the format with "CN=".

Just to understand this a bit more, are Appx always supposed to not be signed? Just the dll/exe's within it?

If you want to send an appx to the Microsoft Store, then indeed it should not be signed since Microsoft manages the signing. See also here: https://www.electron.build/appx#appx-package-code-signing

Based on your logs, it looks like you're receiving a 403 though, can you check your configuration + token?

I think this is because Azure Trusted Signing does not support appx? Since signing works fine for EXE/DLL/MSI but at the end of the electron-builder execution flow it fails since the servers refuse to sign APPX. I am not aware of a configuration toggle to change which extensions can be signed. But for the Microsoft Store release it should not be signed anyway.

@JJ-8
Copy link
Author

JJ-8 commented Mar 11, 2025

Oh forgot to respond to this:

Just the dll/exe's within it?

I can try to bypass this bug by disabling Trusted Signing completely when building the appx release, but this is not what we want. Since after installation, the EXEs/DLLs on disk are then also not signed. And antivirus will not easily trust them for example. We want to have our resources inside the appx to be signed (just like electron-builder is doing right now), but the final appx bundle that is created should not be signed (or at least it should be configurable to be signed or not, but I don't think Trusted Signing supports appx due to the 403 error).

@JJ-8
Copy link
Author

JJ-8 commented Mar 13, 2025

@mmaietta do you perhaps have a time estimate when this issue will be looked into and/or resolved? Currently it is not possible to release our app due to the appx not building correctly. It is no problem if you can't handle this issue at the moment, but if it will take time on the side of electron-builder then I will try to bypass this issue in some way (probably by trying to delete the trusted signing config in a certain hook to prevent it from signing the final package). So it would be great to know if I should invest time in bypassing this bug or not :)

@mmaietta
Copy link
Collaborator

So...my drink leaked in my backpack earlier this week and left my MacBook sitting in a lake for about an hour. It got completely fried. I'm currently waiting to receive it from the Apple repair center.

Can provide an ETA once I receive it and can do a deeper investigation into solutions for you.

@JJ-8
Copy link
Author

JJ-8 commented Mar 14, 2025

Oh wow that's a true nightmare for every developer! I hope your Macbook will survive. But thanks for letting me know. I will wait for your ETA, no problem.

@mmaietta
Copy link
Collaborator

@JJ-8 are Appx files always distributed via MS App Store? I ask since I'm not too familiar with AppX, but it's worth calling out that the signing logic in AppxTarget for signing, in particular, hasn't changed in 8 years
https://github.com/electron-userland/electron-builder/blame/ad151b9dbefa746514dd15471e5ef8bf5eed1d9b/packages/app-builder-lib/src/targets/AppxTarget.ts#L148-L149

@JJ-8
Copy link
Author

JJ-8 commented Mar 17, 2025

@mmaietta no Appx files are not always distributed via MS App Store. You can also sign them yourself with a valid code signing certificate and then you can distribute them to users (think like an in-house enterprise app). But Trusted Signing appears to be not a valid source for a signature, which makes sense since Microsoft would not want to sign your in-house enterprise app. So I think we need to exclude Trusted Signing as a method of signing for Appx (and use the original methods through a normal code signing certificate).

@mmaietta
Copy link
Collaborator

mmaietta commented Mar 17, 2025

Okiedokie, sounds like we need a new property (signAppx, windowsStoreDistributable, other suggestions welcome?) so that builds targeting Windows Store distribution won't specifically sign the Appx file. Will that resolve the issue or do we need additional logic such as this only being applicable to Azure signing?

My MacBook overall did not survive its liquid encounter unfortunately, but the hard drive did at least! So I still have all my git branches, in-progress work, docker config, and VMs 💪 In light of the circumstances, this is one of the better outcomes I could have hoped for lol. Should be able to get a fix on this once we collaborate on what the solution should be. Can easily get it into this release or the next depending on fix scope.

@JJ-8
Copy link
Author

JJ-8 commented Mar 20, 2025

@mmaietta I think a property to indicate if the output appx should be signed or not is a great solution! I remember that I once had to create a separate electron-builder config just to configure it to sign the appx (and therefore by default not sign it with the main config). I think it is therefore a good idea to make this a general config that does not only apply to Trusted Signing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants