How to use mage.exe to resign manifests for VSTO? - c#

We have an Excel plugin as part of our Visual Studio solution. The plugin is built once and then deployed out to different environments (dev, uat, prod) as part of our CI/CD process.
During the deploys we apply an app config transform to update the Excel plugin config with the correct environmental config.
As such, the manifest and VSTO needs resigning. I've been through a number of SO posts (Use mage.exe to create a ClickOnce deployment manifest for *.deploy files, Resign manifest of click-once application change from 4.0 to 4.5, Resign Clickonce manifest using mage.exe etc.) and MSDN posts and cannot work out the correct way to call mage.exe for this to work.
I've tried mage.exe -update ..., mage.exe -sign ... and a couple of other combinations that all result in broker or invalid manifests when I try to launch the VSTO e.g.
C:\Tools\mage.exe -update "$CodeBasePath\MyCompany.vsto" -certFile "$CertFile" -password "$CertPassword" -appManifest "$AppManifestPath"
Does anything know the correct order of signing and flags to use with mage.exe when re-signing a VSTO?

before updating the VSTO file you need to first update the application manifest.
mage -update yourFile.dll.manifest -CertFile certificate.pfx -Password password
Then you need to update the VSTO with the application manifest you already updated.
mage -update yourFile.vsto -appmanifest yourFile.dll.manifest -CertFile certificate.pfx -Password password

just additional info to the above correct answer is, incase using Certificate Store or USB Token, then you need to provide -CertHash "certificate thumbprint" instead of -CertFile "certificate file path"
mage -update yourFile.dll.manifest -CertHash "cert-thumb-print"

Related

Signing a Excel/VSTO project without pfx file

I have a VSTO project which combines C# and Excel. My employer requires me to sign this using a certificate for which I do not have a pfx file, I only have the certificate on a chip card.
I have read most manuals and questions asked here on signing VSTO, but all somehow assume I have the pfx file. My setup in Visual Studio is the following:
„Sign the ClickOnceManifest“ is checked, using „Select from Store„ the certificate from a chipCard is selected
„Sign the Assemly“ is checked. I do not have the pfx file, so I hit „New“ and created a certificate called assemblySigningCertificate.pfx (this might be a completely bogus step, but that's the only pfx I get)
after publishing the project, I run a script that updates the signatures using mage.exe such as
set AppPublishPath=publish
set AppPublishVersionPath=publish\Application Files\diagramUnifier_1_0_0_0
copy bin\Debug\*.dll "%AppPublishVersionPath%"
copy bin\Debug\*.dll.config "%AppPublishVersionPath%"
copy bin\Debug\*.exe "%AppPublishVersionPath%"
mage.exe -update "%AppPublishVersionPath%\diagramUnifier.dll.manifest" -ch "… certificate hash from certmgs.msc "
mage.exe -update "%AppPublishVersionPath%\diagramUnifier.vsto" -appmanifest "%AppPublishVersionPath%\diagramUnifier.dll.manifest" -ch "… certificate hash from certmgs.msc "
mage.exe -update "%AppPublishPath%\diagramUnifier.vsto" -appmanifest "%AppPublishVersionPath%\diagramUnifier.dll.manifest" -ch "… certificate hash from certmgs.msc "
Once all this is done, I install the VSTO and run the xlsm file. I receive a "SignatureDescription could not be created from the signature algorithm supplied" error pointing to the VSTO file. Details of the error provide only a stackTrace, nothing else.
My questions are:
is it even possible to sign a VSTO project without a certificate for which I have a pfx file?
if I don’t have the pfx file, is it the right thing to create a new certificate in the “Sign the assembly” section of settings
am I doing something else entirely wrong?
Any help is much appreciated,
Daniel
Problem: When a certificate is created by using selfcert.exe, it's private key cannot be exported. The export wizard of the Windows certificate console says "the associated private key is marked as not exportable".
Solution version 1: Use makecert.exe with the "-pe" option to create
and store the certificate with an exportable private key:
makecert -r -pe -n "CN=Your Name" -b 01/01/2000 -e 01/01/2099 -eku 1.3.6.1.5.5.7.3.3 -ss My
Then you can export the certificate from the Windows certificate store, including the private key.
Note: Old versions of makecert.exe do not support the "-pe" option. The .NET Framework SDK 2.0 and the October 2002 version of the Platform SDK (build 3718.1) contain a new version of makecert.exe (5.131) that supports the "-pe" option.
(The .NET Framework SDKs 1.0 and 1.1 both contain old versions of makecert.exe that do not support the "-pe" option).
Solution version 2: The following commands can be used to create a PFX
file (PKCS #12) that contains the a self-signed certificate together
with the associated private key:
makecert -r -n "CN=Your Name" -b 01/01/2000 -e 01/01/2099 -eku 1.3.6.1.5.5.7.3.3 -sv selfcert.pvk selfcert.cer
cert2spc selfcert.cer selfcert.spc
pvkimprt -pfx selfcert.spc selfcert.pvk
The last command (pvkimprt -pfx) creates the file selfcert.pfx. This PFX file can then be imported into the Windows certificate store and used for code signing.
(makecert.exe and cert2spc.exe are part of several Microsoft SDKs, e.g. the Platform SDK or the DotNet SDKs, which can be downloaded from microsoft.com. pvkimprt.exe can be downloaded individually from Microsoft.)
Are you saying that you do not have the private key for the certificate? If that's the case then you definitely cannot sign the assembly/installer. The whole point of signing is to certify that the assembly comes from a trusted/certified source (ie. the certificate (private key) holder).
Who is your employer? Larger companies have processes in place to get installers and assemblies signed via their IT/Security department. I'd double check that is not the case where you work.
On another point... Do you have .NET4.5 installed? See here it might help...
This change is due to the fact that we stopped using legacy
certificates as default (SHA-1) in NetFX4.5 to sign manifest and
instead, use newer version (SHA-256), which is not recognized by
NetFx4.0 runtime. Therefore, while parsing the manifest, 4.0 runtime
complains of an invalid manifest. For legacy frameworks, when we try
to run a ClickOnce app on a box that does not have targeted runtime,
ClickOnce pops up a message to user saying “you need xxxx.xx runtime
to run this app”. But starting .NET 4.5, if a 4.5 ClickOnce app is run
on the box with only .NET 4.0 installed, the message complains about
an invalid manifest. In order to resolve the issue, you must install
.Net Framework 4.5 on the target system.

Signing office COM Add-in

I've developed an extension based on NetOffice. My office configuration requires applications to be signed by Trusted Publishers. I tried signing the output DLL with signtool.exe, with a valid certificate, but unfortunately, Office says "There is no digital signature available".
The option can be enabled via:
File → Options → Trust Center → Trust Center Settings → Add-ins → Require application Add-ins to be signed by Trusted Publisher
What's the appropriate method for signing the DLL?
When using VSTO, ClickOnce handles the signing, also there's a .manifest file that is created for the DLL, I'm not sure if its required or not but I'm unable to create one for my class library.
Some info that I found online:
https://msdn.microsoft.com/en-us/library/bb772096(v=vs.120).aspx
https://msdn.microsoft.com/en-us/library/bb386179.aspx
https://msdn.microsoft.com/en-us/library/che5h906.aspx
First, create a .pfx file with pvk2pfx.exe:
"C:{PATH}\pvk2pfx.exe" -pvk {PVK FILE NAME} -pi {cert owner name} -spc {SPC FILE NAME} -pfx {PFX FILE NAME}
e.g.: "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\pvk2pfx.exe" -pvk mypvkfile.pvk -pi companyname -spc myspcfile.spc -pfx mypfxfile.pfx
Then use the SignTool.exe utility:
signtool sign /f "C:{PATH}\mypfxfile.pfx" /p {cert owner name} "C:{PATH}\setup.exe"

Getting permission for accessing an existing file in setup created using Inno Setup

I am a new C# programmer. I made a setup file of an application in Inno setup, but when I use this application after installation, the application crashes when it tries to access (read) an existing folder in the computer (which the user has permission to access otherwise). This folder does not contain any program file, or logs. It just contains some media files which are already in the computer.
I saw the Inno script format, but it shows only how to give permission to access program files/folders only, what about the files which are already there in the computer? Shouldn't the application should have access to files which the user (who installed it)has access to ?
To set permissions on existing files or folders, you can use the Windows cacls command in the [Run] section.
Filename: "{sys}\cacls.exe"; Parameters: """C:\My Folder\My File.ext"" /t /e /g ""Everyone"":f ""Power Users"":f ""Users"":f ""Authenticated Users"":f "; StatusMsg: "Configuring Windows settings..."; Flags: runhidden
Type cacls /? at a command prompt for all available switches and syntax.
It worked when I used
"Permissions: users-modify" in [Dirs] section.

How to correctly sign an executable

I have made a little tool. It is a console application that when running on Win7 brings the UAC security prompt.
I tried to sign this EXE file in Visual Studio 2010 using the following steps:
Project properties
Signing
Create new key as shown below
The key file was successfully created, as you can see in the capture below.
Issues:
File is still being blocked by the UAC security prompt. When I checked the file whether signed or not using the signtool.exe, it tells me, no signature was found.
Please correct me if I'm following the wrong steps.
Assembly signing != Authenticode signing.
To authenticode sign an assembly with signtool, you'll need a code signing certificate from a trusted issuing authority.
You can then issue the following post-build command to sign your executable:
"signtool.exe" sign /f "$(SolutionDir)myCertificate.pfx" /p certPassword /d "description" /du "http://myinfourl" /t "http://timeserver.from.cert.authority/" $(TargetPath)
Everything you need to know about Authenticode Code Signing
Basically you have 2 options, using a command that you manually execute or execute via a batch file
signtool.exe sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /f "D:\Source\Certificates\CodeSign.pfx" /as /p MyPassword "{path to exe}"
becomes a bit frustrating after a while
Better add it on your project's option page in the Build Events.
In your post build you would enter
call "C:\Program Files (x86)\Windows Kits\10\bin\x64\signtool.exe" sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /f "D:\Source\Certificates\CodeSign.pfx" /p MyPassword $(TargetPath)
the Macro $(TargetPath) will be filled with the path to your compiled exe or dll.
Now each time you compile you will get a signed file.
Would look something like this:

Is there a way to alter the update URL for installed click once applications

We have been using click once since 2006 and now have a need to change the update location, this happened once before but we just uninstalled and reinstalled, this will now be problematic.
A solution was presented in Click Once Migrate URL, however when we tried this years ago (.NET 2.0), it failed with the app stating that the URL of the update and the URL of the client did not match raising a security risk and prevented the update from occurring and starting for that matter.
The docs state that this property can only be altered in the application manifest, but I'm not sure the approach to actually change this in an already deployed app.
I want to use a process such as the following assuming current version is 5 and deployment location is apps.mycompany.com and new location is clickonce.mycompany.com
Publish app at clickonce.mycompany.com with version 5.2
Publish app at apps.mycompany.com with version 5.1 which has bootstrapping code when the app starts up to alter the apps manifest to change the URL.
With this process the clients will then get two new updates consecutively. Infect, if I publish 5.1 to both locations it should work.
This type of thing can be solved by having the app uninstall itself, and then reinstall itself. I have done it before, although I was installing from a network location, and not a url, but it should be the same thing.
Here is a link on msdn for this solution. Go down to the section "How to programmatically uninstall a Click Once application and install a new version".
You can also check out a different version of the solution here.
This works, but it's a bit tricky. It is the only way I know of to solve this type of problem though.
EDIT If you use the information in that article, here are 2 things to watch out for.
Make sure the update for the app that is uninstalling itself is not optional. You need to make the required version be the current deployed version. Otherwise, the restore option is available and is the default for the uninstall dialog box, and the app won't uninstall itself.
Make sure in the GetUninstallString method in the DeploymentUtils class, change the DisplayName it is looking for from "TestCertExp_CSharp" to the name of your app.
use these command lines
mage.exe -Update setuptest_1_0_0_2.application -ProviderUrl http://127.0.0.1/setuptest/setuptest.application
mage.exe -Update setuptest_1_0_0_2.application -AppManifest setuptest_1_0_0_2\setuptest.exe.manifest
mage.exe -Sign setuptest_1_0_0_2.application -CertFile setuptest_TemporaryKey.pfx -Password mypassword
mage.exe -Update setuptest.application -ProviderUrl http://127.0.0.1/setuptest/setuptest.application
mage.exe -Update setuptest.application -AppManifest setuptest_1_0_0_2\setuptest.exe.manifest
mage.exe -Sign setuptest.application -CertFile setuptest_TemporaryKey.pfx -Password mypassword
Check this: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2939893&SiteID=1

Categories

Resources