Skip to content

ClickOnce EV code sign with USB HSM add support for EDCSA keys #256

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

Open
RhomGit opened this issue Mar 8, 2023 · 16 comments
Open

ClickOnce EV code sign with USB HSM add support for EDCSA keys #256

RhomGit opened this issue Mar 8, 2023 · 16 comments
Labels
area-ClickOnce enhancement New feature or request

Comments

@RhomGit
Copy link

RhomGit commented Mar 8, 2023

Description

I am manually signing application manifest via mage.exe or mageui.exe.
I have an EVCS from a CA issued on a USB HSM (Yubikey).
signtool.exe has signed the executable correctly using the HSM.
mage.exe is reporting "This certificate does not contain a private key"
mageui.exe is asking for a Certificate file which I don't have.
image

To Reproduce

Try and sign a manifest file using a USB HSM.

.\mage.exe -Sign "C:\my_app.exe.manifest" -csp "Microsoft Smart Card Key Storage Provider" -kc "9b5…" -CertHash "c15…"

Exceptions (if any)

"This certificate does not contain a private key"

Configuration

C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8.1 Tools>

Other information

I have a ticket open with Visual Studio here: https://developercommunity.visualstudio.com/t/ClickOnce-EV-Signing-with-HSM/10278648

I can use signtool to successfully use the HSM for EVCS. This works and I just need mage to do the same. I run the following in PowerShell which prompts for PIN and works perfectly:

cd "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64"
.\signtool.exe sign /fd sha256 /tr http://ts.ssl.com /td sha256 /n "UniqueStringInMyCertificate" "C:\My.exe"

Some others have reverse engineered mage to get this working: https://stackoverflow.com/questions/54752638/mage-exe-manifest-signing-with-certificate-stored-in-aws-cloudhsm

I am happy to help give more feedback/troubleshooting to help resolve this issue. It is affecting many of our clients (today has been awful) as its been sitting triaged for 3 weeks in the other forum and this looks like the appropriate repo for mage. Thanks

@ghost ghost added the untriaged label Mar 8, 2023
@Tanya-Solyanik
Copy link
Contributor

I see multiple potential issues here:

  1. Signing using MAGE fails when providing -CertFile -CryptoProvider and -KeyContainer microsoft/dotnet#986 (comment) - add a code path that attempts to create an Exchange key if a Signature key wasn't found.
  2. Certificate is potentially using SHA384, which is not supported by the build task because SHA2 is hardcoded, even though providers might be available.

@Tanya-Solyanik
Copy link
Contributor

It's possible that the certificate @RhomGit is using has an elliptic curve key, then this is not supported by mage, as it has RSA providers hardcoded in places. In this case your best option is to request a new key.

@RhomGit - to eliminate the easy case, are you using a 64 bit version of mage? Does 64 vs 32 bits make a difference?

@RhomGit
Copy link
Author

RhomGit commented Mar 24, 2023

It was 32 bit. I saw your previous post and downloaded the https://dotnet.microsoft.com/en-us/download/dotnet-framework/thank-you/net481-developer-pack-offline-installer and it did indeed place a mage.exe in the x64 subfolder in the Program Files (x86) directory :)
C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8.1 Tools\x64\mage.exe

I am heading out to the office now to test (as you can't use the keys over RDP). I will post back soon!

@Tanya-Solyanik
Copy link
Contributor

You would want the latest version as some fixes related to HSM were shipped over time.

To answer your other questions - where to get the .cer file. You should be able to export the public key from your hardware. Perhaps the crypto provider adapter suggests a different file extension for the exported file. For example, Yubico UI suggests .crt or .pem extensions, you can change this extension when exporting.
image

To find out if your key is a signature or an exchange key, run the certutil -scinfo command, find your key container in the output and then search for key information

 Key Container = your container
  Provider = your provider
  ProviderType = 1
  Flags = 1
    0x1 (1)
  KeySpec = 2 -- AT_SIGNATURE

The important piece is KeySpec. Mage supports only value 2.
If you see:

KeySpec = 1 -- AT_KEYEXCHANGE

Your fastest option is to either request a new certificate or to follow this workaround - Signing using MAGE fails when providing -CertFile -CryptoProvider and -KeyContainer · Issue #986 · microsoft/dotnet (github.com)

@RhomGit
Copy link
Author

RhomGit commented Mar 24, 2023

Alas, I tried x64 and still get this:
This certificate does not contain a private key - "xyz"
This certificate cannot be used for signing - "xyz"

  Provider = Microsoft Smart Card Key Storage Provider
  ProviderType = 0
  Flags = 1
    0x1 (1)
  KeySpec = 0 -- XCN_AT_NONE
Private key verifies
Microsoft Smart Card Key Storage Provider: KeySpec=0
AES256+RSAES_OAEP(ECC:CNG) test skipped

I have updated to latest YubiKey Manager. Re-downloaded and re-imported the key and still the same results.

I contacted SSL.com to see about a new certificate and finally got a decent response from them.
image

I am opting for OV for now since I am in such a predicament with a wide user base.
https://www.ssl.com/faqs/which-code-signing-certificate-do-i-need-ev-ov/#smartscreen

Note: I have had issues with eSigner and refuse to use it ever again.

As recommended I have added this a feature request: https://developercommunity.visualstudio.com/t/Add-support-to-ClickOnceMAGE-for-certif/10320755?port=1026&fsid=a18cb832-d063-456d-84c4-51e0dfcabdf2

Thanks

@Tanya-Solyanik
Copy link
Contributor

Tanya-Solyanik commented Mar 24, 2023

@RhomGit thank you for the details. So your actual request is for mage and ClickOnce to support EDCSA. I'll modify the bug title accordingly.

@Tanya-Solyanik Tanya-Solyanik changed the title ClickOnce EV code sign with USB HSM - This certificate does not contain a private key ClickOnce EV code sign with USB HSM add support for EDCSA keys Mar 24, 2023
@RhomGit
Copy link
Author

RhomGit commented Apr 24, 2023

Hi, @Tanya-Solyanik I am sorry to say that this continues to be a thorn in our business.

OV has unfortunately not been a viable solution as now many of our client organisations are being confronted with SmartScreen (which is embarrassing and confusing to users) and some are having to engage their own I.T departments to workaround the solution every time we publish an update.

I appreciate all of your consideration up to this point however I need to make a serious decision on this so if I could please have some information to go by:

  • Is there a timeframe for adding this support?
  • Can we offer you money to expedite this?
  • What is the likelihood of this being added?
  • Can you suggest an alternate CA who provides EVCS keys in a format that ClickOnce does support?

I do value and appreciate your responses thus far.

Thanks,
Denis

@RhomGit
Copy link
Author

RhomGit commented May 10, 2023

We have decided to engage with alternate CA's to find one that still supports the older RSA method.

@RhomGit RhomGit closed this as completed May 10, 2023
@RhomGit
Copy link
Author

RhomGit commented May 19, 2023

For anyone trying to use EVCS with ClickOnce I'll keep a list of here of engaged CAs trying to find someone who still supports KeySpec = 2.

The important piece is KeySpec. Mage supports only value 2.

SSL.com

Yubikey was KeySpec = 0 as above.

GlobalSign

response was:
We’ve just checked, the KeySpec for our EV CodeSigning certificate is value 1. So the difference is, a KeySpec value of 1, or AT_KEYEXCHANGE, can be used for signing and encryption and value of 2, or AT_SIGNATURE, is only used for signing. May I know if this is acceptable or is there a specific reason that you need the certificate to specifically be KeySpec = 2?

Digicert

Note: many CA seems to use digicert (including Thawte)
Great company, very supportive and provided what I required once company was validated. Highly recommended.

@RhomGit RhomGit reopened this May 19, 2023
@tbrentlong
Copy link

Was any resolution reached on this? We have ClickOnce apps as well and need to be able to sign them in a way that shows publisher. We use Azure HSM Key Vault for our cert and it works fine using AzureSignTool to sign the DLLs/EXEs -- but not sure how to handle the ClickOnce manifest signing.

@RhomGit
Copy link
Author

RhomGit commented Nov 20, 2023

I moved to Digicert as my CA who supports KeySpec==2 via physical HSM and published to ClickOnce via Visual Studio directly.

There are instructions here: https://github.com/dotnet/sign for AzureSignTool + ClickOnce support.

@plutext
Copy link

plutext commented Nov 23, 2023

The important piece is KeySpec. Mage supports only value 2.

Actually it seems like Command.cs only supports value 1: https://github.com/search?q=keyspec+repo%3Adotnet%2Fdeployment-tools+&type=code

After building this repo, the following works for me:

deployment-tools>.dotnet\dotnet  C:\Users\jh\deployment-tools\artifacts\bin\MageCLI\Debug\net7.0\dotnet-mage.dll -Sign Foo.dll.manifest -csp "eToken Base Cryptographic Provider" -kc "p11#9c60b9999972999d" -CertHash "ffd...2e7"
Foo.dll.manifest successfully signed

This is using a HARICA code signing certificate, which has spec AT_KEYEXCHANGE.

@MarkEdward
Copy link

@plutext Did you modify the Command.cs file, or use the current version of the repo as is?

Looking at the history of Command.cs, I don't see what has changed that would make KeySpec == 0 / XCN_AT_NONE certificates work? (I'm using a Yubikey certificate, and so that's the KeySpec type I'm trying to get working in mage)

@Connect-and-Exchange
Copy link

Same issue here, ubikey with EV certificate. Following this thread and hopefully mage.exe can be updated to support the EV certificates as well.

@NikolaMilosavljevic NikolaMilosavljevic added enhancement New feature or request and removed untriaged labels Feb 6, 2024
@jamiehankins
Copy link

Almost a year later, is this support even on Microsoft's roadmap?

Given that signtool can work work these certificates, why can't a dev be assigned to fix dotnet-mage to use the same?

Is ClickOnce no longer a recommended technology from Microsoft?

@LunevNF
Copy link

LunevNF commented Mar 20, 2025

Does anyone have a working way to sign manifests using RuToken v 3.0 (Global Sign)?
I've tried everything.
Exception here: SecurityUtilities.SignFile(storedCert, timestampUrl, outputPath); (The requested operation is not supported.)
I did a debug, all the parameters are there, but it doesn't want to sign the manifest in any way if KeySpec == 1 (AT_KEYEXCHANGE).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-ClickOnce enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

10 participants