Signing and re-signing manifests in ClickOnce (Saurabh Bhatia)

Rate This
  • Comments 22

ClickOnce manifest signing can be a little confusing for someone going through the process the very first time. This is probably because it involves signing multiple files in a particular sequence. Once you understand the process conceptually it becomes fairly easy to follow. In this post, I hope to provide a quick summary of the important thingsyou need to know about manifests and this signing/resigning business.

Let’s start with some background info in case you missed it:

What are these manifests I speak of?

Any application deployed through ClickOnce will have two manifests: a deployment manifest and an application manifest.

Depending on the type of application, the deployment manifest can have the following file extensions:

.application – for any executable application like a Winforms or WPF application

.vsto – for a VSTO based Office customization solutions (which this blog is all about)

.xbap – for a Browser Hosted WPF application

An application manifest will always have the .manifest extension. For example:

.exe.manifest – for any executable including Winforms, WPF and Browser Hosted WPF applications.

.dll.manifest – for VSTO based office customizations.

MSDN has documentation that describes these files and their use in detail but for a one line summary – think of these as “Setup Authoring” for your application that tells the application how to install, update, what the application is called etc.

ClickOnce Application Manifest

ClickOnce Deployment Manifest

Application Manifests for Office Solutions (2007 System)

So why do manifests have to be signed?

The ClickOnce “trust model” is based on signing the ClickOnce manifests with a Certificate. By “trust model,” I mean the process by which ClickOnce and the end user can decide whether to trust an application and allow it to install or not. To sign an application, you need a Certificate - Visual Studio will generate a temporary certificate for you when you publish an application (like MyApplication_Temporary.pfx) and also sign the manifests for you. You can also choose to sign the manifests with a code-signing certificate that you can obtain from a Root Certificate Authority.

These MSDN articles go into details about the certificates and how they are used:

ClickOnce Deployment and Authenticode

Signing ClickOnce Manifests

Starting with .NET 3.5 SP1, signing has become optional for any .exe-based application. So Winforms/WPF/Console applications deployed via Clickonce no longer need to be signed. The downside of course is that there are no guarantees on the integrity of the application. The developer has to make the choice between the tradeoff of securing the application and going through the signing process vs not signing the application at all and relying on some other means of ensuring the application has not being compromised.

Note that VSTO solutions still require that the manifests be signed. Most VSTO scenarios are in the enterprise where best practices require signing of applications. Also since VSTO solutions always run full trust there is a higher risk associated with making signing optional.

Why do they need to be re-signed?

Visual Studio is capable of generating signed manifests. Why get into this whole re-signing business? Re-signing is needed when you are in a situation where you want to change something about the application after it has already been published – and you want to do so without re-building or re-publishing the application from Visual Studio.  You may want to simply sign the application with a different certificate without re-building the application, for example you test the application with a self created test certificate but when you deploy the application to end users it is signed with a code-signing certificate issued by a Certificate Authority. Some of the most common examples that re-quire re-signing are when you want to change a particular file that is part of your application like the .config file, or maybe a simple resource/data file that is deployed along with your application.

The ClickOnce manifests contain hashes to all the files that are being deployed as part of the application. If any of the files change, then the hash for that file breaks and the signing becomes invalid. So you cannot simply replace an individual file in a ClickOnce package without breaking the signing. You will have to update and re-sign the manifests if you want to update a file.

The following figures should help illustrate this better.

clip_image002

A typical ClickOnce deployment package consists of

· Deployment Manifest

· Application Manifest

· Application Files – the exe and dlls associated with the application.

The deployment manifest links to the application manifest along with the hash of the application manifest, so if the application manifest changes the hash will no longer be valid. Similarly the Application manifest links to all the application files along with their hashes.

So consider the situation where one of the application files say the .config file in this case changes after the app has been published.

clip_image004

Since the .config file changed the hash in the Application Manifest will not match up to the new file anymore. Trying to install the application in this state will fail (unless you are using optional signing and hashing of course).

You will have to update and re-sign the application manifest in order to get the deployment to work again.

You can do this using the following mage commandline:

Start the Visual Studio command prompt. Locate the application manifest folder. Typically under “%Publish Folder%\Application Files\MyApplication_Version\Myapplication.exe.manifest”

Use the –update option for the mage command line.

> mage –update Myapplication.exe.manifest –certfile mycert.pfx

The update command will update all the file hashes defined in the application manifest to match those of the files located next to it. For other options on how to use update see MSDN: Manifest Generation and Editing Tool (Mage)

Note: While update the application, you might see some errors about Files not found. This could happen if you using the .deploy extensions for you application files. To avoid this, you must rename the .deploy extensions back to their original extensions and then run the update command with mage. Once you have update the application manifest, you must rename the application files back with he .deploy extension.

Once you have updated the application manifest with mage, all the files it refers to will have the correct hashes. However at this point since the application manifest itself is updated, the hash to the application manifest contained within the deployment manifest will no longer match.

clip_image006

To fix this the deployment manifest needs to be updated with the hash of the new application manifest and re-signed.

The mage command line to do this:

> mage.exe –update Myapplication.application –appmanifest “Application Files\MyApplication_%Version%\Myapplication.exe.manifest” –certfile mycert.pfx

clip_image008

At this point, all the hashes to all the files have been updated and both manifests have been re-signed. So the application is ready to be installed on the end users’ machine without re-building or re-publishing from Visual Studio.

In the above example I chose to show how the resigning process is done through the Mage command line tool. The same process can be done through the MAGEUI tool which provides a GUI for the manifest editing. For simply re-signing your manifests I have always preferred to use the command line. The re-signing process itself can be straightforward once you understand the need for it. Most users forget to either update or sign both manifests and I hope this post illustrates the chaining dependency and why both manifests need to be updated.

Leave a Comment
  • Please add 7 and 1 and type the answer here:
  • Post
  • @nirmal which version of mage are you using? Can you try with the latest 4.0 version of mage commandline -> The one that ships with VS2010 or the VS SDK.

    I believe there might have been an issue around this with an earlier version of the commandline tool.

    Thanks

    Saurabh

  • i tried to re-sign the manifest files for my code signed files....by creating new application manifest and deployment manifest.. using both Mage and Mage UI... but in vain... i have lost the count of errors that i got. I somehow knew that the only thing needed to be tweeked are the manifest files... but had no clue about the -update option...phewww!!... this really really helped me... thanks a ton Saurabh for savin me from the frustration :)

  • Hi,

    First thanks a lot for the info. It has helped me a lot.

    I was trying to achieve this in code, since i have so many files .deploy files and renaming then by hand is not an option, so i wrote a little application to modify the web service reference. I am trying to sign the app manifest in code too but when installing the application i get an error about the hash being different in the .config file. Any ideas? Can I actually do this?

    ApplicationManifest appManifest = ManifestReader.ReadManifest(szManifest, true) as ApplicationManifest;

               X509Certificate2 cert;

               cert = new X509Certificate2(pfx);

               SecurityUtilities.SignFile(cert, null, szManifest);

  • I am getting the following error when I tried the procedure given by you above. Can you please suggest what could be the problem here.

    Name: Unesco.Steps.LetterCreation.ModelTemplate

    From: file://dlx/temp/LetterCreationModelTemplate/Unesco.Steps.LetterCreation.ModelTemplate.vsto

    Exception reading manifest from file://dlx/temp/LetterCreationModelTemplate/Application%20Files/Unesco.Steps.LetterCreation.ModelTemplate_1_0_0_0/Unesco.Steps.LetterCreation.ModelTemplate.dll.manifest: the manifest may not be valid or the file could not be opened.

    ************** Exception Text **************

    System.Deployment.Application.InvalidDeploymentException: Exception reading manifest from file://dlx/temp/LetterCreationModelTemplate/Application%20Files/Unesco.Steps.LetterCreation.ModelTemplate_1_0_0_0/Unesco.Steps.LetterCreation.ModelTemplate.dll.manifest: the manifest may not be valid or the file could not be opened. ---> System.Deployment.Application.InvalidDeploymentException: Application manifest is not semantically valid. ---> System.Deployment.Application.InvalidDeploymentException: Application manifests must specify exactly one <entryPoint> section.

      at System.Deployment.Application.Manifest.AssemblyManifest.ValidateSemanticsForApplicationRole()

      --- End of inner exception stack trace ---

      at System.Deployment.Application.Manifest.AssemblyManifest.ValidateSemanticsForApplicationRole()

      at System.Deployment.Application.Manifest.AssemblyManifest.ValidateSemantics(ManifestType manifestType)

      at System.Deployment.Application.ManifestReader.FromDocument(String localPath, ManifestType manifestType, Uri sourceUri)

      --- End of inner exception stack trace ---

      at Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInDeploymentManager.GetManifests(TimeSpan timeout)

      at Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInDeploymentManager.InstallAddIn()

  • Hi Saurabh,

    Basically I wanted to do the same thing which you explained but scenario here is bit different,

    We have developed a click-once application which has Access database at back-end, this application is installed in about 30-40 laptops already.

    Now, We update our database every day and I upload this Access database to our website and users who are using this application simply click on button which provided in application and It will replace the database which they currently using with the NEW database which I have uploaded on website.

    But If we update application it self and upload that new version of application on website, user will get message box at start of the application that new updates are available and when they try to update , It comes up with error message that "database_name.mdb has different hash value" and it won't allow to update application.

    Now I know when replace database with new database, I have to update Manifest as well but I dont know how to update manifest of already installed clickonce application.

    Any help please ??

    Thanks

  • en.wikipedia.org/.../Accidental_complexity

  • If the published software conatins only the "Application Files" folder then how to update the maniifest

Page 2 of 2 (22 items) 12

Signing and re-signing manifests in ClickOnce (Saurabh Bhatia)