6
votes

I have a VSTO program in Visual Studio 2017. In order to make the install process run more smoothly when I publish via ClickOnce and host the files on the web, I bought an EV Certificate from DigiCert.

This is what I bought - https://www.digicert.com/code-signing/ev-code-signing/

So I waited a couple days, got my USB token, set everything up and now when I sign the app with my fancy new certificate... the install flat-out fails.

The error the user gets is: Customized Functionality in this application will not work because the certificate used to sign the deployment manifest for AppName or its location is not trusted. Contact your administrator for further assistance.

I contacted DigiCert for tech support and they basically said that this is an error with Visual Studio 2017 and the Operating System.

I then called Entrust to see if they could confirm since they also have the EV Certificates: https://www.entrust.com/code-signing-certificates/#ev-code-signing-certificates

Turns out I guess until you buy one, they can't answer the question. They just kindof say "buy it and try it and if it doesn't work we'll give you your money back."

How is it possible that nobody knows how to sign an install from Visual Studio?

I would love to be able to sign this install and get it to work.

2
Did you ever figure this out?Frederik Hansen
yes i did... forgot to post the answer... will do now.gotmike
@FrederikHansen -- take a look at the answer... hope that helps.gotmike

2 Answers

7
votes

After a lot of time spent on the phone with support at DigiCert, we finally figured out a process that works.

What is not immediately obvious in this case is that you end up doing a LOT of signing of code.

So when you build a VSTO application, you sign the code with the EV certificate. Then, when you want to publish (using ClickOnce) you will have to sign again.

But even after that, you have to then re-sign the setup file TWO MORE TIMES to get this all to work!

After spending a ton of time on this, I now have a batch file that does the final steps, including syncing the setup files up to Amazon S3 for deployment.

So here's how I do it:

  1. Once you have the USB dongle installed, you setup the "Signing" section of your app in Visual Studio to reference the correct certificate.
  2. Right-click your project and click Build (or Rebuild to be safe) and you will have to sign using the dongle.
  3. Now, right-click the project and pick Properties
  4. Inside Properties go to Signing and confirm you have the correct certificate selected. If you skip this step, the app won't install.
  5. Still inside Properties go to Publish and make sure to set your publishing location and installation folders. I use Amazon S3 for the installation folder.
  6. Click Publish Now. It will ask you to sign again.

Now, you would think at this point you'd be done... but you aren't.

  1. So what you need next is a .p12 certificate. I contacted DigiCert support and they were able to give me one for free (prob just for a year) since I was having so many problems. This is different than the EV certificate.
  2. After you have the .p12 certificate AND the EV, I run the following batch routine, which signs the setup.exe file TWICE (once with .p12 and then again with the EV) and also pushes up to Amazon S3.

Here's my SignDeploy.bat file:

echo off
cls
echo Signing setup.exe with .p12 Certificate File
"C:\Program Files (x86)\Windows Kits\10\bin\x64\signtool.exe" sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /f [LOCATION OF P12 FILE] /p [PASSWORD] [LOCATION OF SETUP.EXE]
pause
echo Signing setup.exe with EV Certificate from Store
"C:\Program Files (x86)\Windows Kits\10\bin\x64\signtool.exe" sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /sha1 [EV HASH FROM DIGICERT] [LOCATION OF SETUP.EXE]
pause
echo Dry run on syncing files up to S3
aws s3 sync [LOCAL DEPLOYMENT FOLDER] [S3 BUCKET AND FOLDER LOCATION] --acl public-read --dryrun
echo  
echo If that worked, it's time to send them up for real.
echo Control-C to stop now, or...
pause
aws s3 sync [LOCAL DEPLOYMENT FOLDER] [S3 BUCKET AND FOLDER LOCATION] --acl public-read
pause

After all this (I think you end up typing your EV certificate password 3 times total) a user who downloads setup.exe from the specified location (must be the same as indicated in your app) will be able to install and run your VSTO application.

There are other problems we have run into along the way with the installation process on the client side, but using the above process solves the issue with signing.

I won't pretend to understand why this needs signed so many times, nor does it make sense that this doesn't all work smoothly from inside Visual Studio. DigiCert tried to have me use Build Events to do this, but it doesn't work b/c those processes run on either side of the BUILD not the PUBLISH. What we'd need are Publish Events which I don't think exist.

I have explored the idea of a longer more involved command-line process using MsBuild.exe, but it's difficult to do the Automatically increment revision with each release part that way.

Maybe someone here has an idea how to set that up. My process is still a bit manual, but it seems to work reliably at this point so I'm not inclined to mess with it too much.

1
votes

What to sign and why

  1. Visual Studio relies on SignTool to sign the Setup.exe of the App it builds. This is because Windows will run an integrity check when installing a new app. This is Authenticode technology, for any software run via Windows.
  2. However, because we are under the context of a VSTO, and because Microsoft Office verifies the integrity of COM Add-Ins each time they are called, you also need to sign your project DLL via the Manifest Generation and Editing Tool. This is Mage technology, specific for deployment manifests such as theses relied upon by ClickOnce.
  3. Because we are under the context of a ClickOnce deployment, you also need to sign the deployment manifest, which guarantees the link to the remote location which contains the installation files is legit. This is Mage technology.
  4. And Finally, ClickOnce also requires to sign the application manifest; that is, the listing of all the files included in the release (setup.exe / main DLL, and others requisites such as supporting DLLs). This is Mage technology.

Worth noting

In the past, in terms of security Authenticode stepped ahead faster than Mage: Authenticode required to sign SHA256 digests, whilst Mage only supported SHA1 digests. Hence the requirement to sometimes sign the same file twice. See full topic here.

This however, seems to be a problem of the past.


How to proceed

I am using an EV code signing dongle provided by Sectigo. All I have to do to sign and publish the solution via ClickOnce is:

  1. Run SafeNet Authentication Client Tools
  2. Plug the dongle and make sure it appears in the SafeNet client
  3. In Visual Studio (VS 2017 here), go to Project / Properties / Signing and choose [Select from Store...]
  4. Publish the solution (Publish Tab, click [Publish Now])
  5. SafeNet will ask you for the Signing Certificate password. Note sometime you may have to type your password twice, not sure why.
  6. The Solution is fully published and all relevant documents mentioned above are signed.