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

Rate This
  • Comments 23

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 2 and 3 and type the answer here:
  • Post
  • PingBack from http://asp-net-hosting.simplynetdev.com/signing-and-re-signing-manifests-in-clickonce/

  • I just posted another interview on Channel 9 . I sit down again with Saurabh Bhatia, a Program Manager

  • Ohhh noooo. Just when I thought deployment was going to be easy with ClickOnce I see that I still cant do optional hashing and signing with a VSTO project.

    It is such a great feature for windows apps. Now I need to create a new install for each client - a client will never go through the above process.

    I await this in a future release.

  • Is there any option to see that the Word document is using a VSTO file signed by the CA... Can user view the certificate information that signed the VSTO (the VSTO manifests has been signed)?

    please advice..

  • hi Din,

    Saurabh has written about this area in http://blogs.msdn.com/vsto/archive/2008/06/11/specify-a-product-name-publisher-name-and-other-properties-for-vsto-solutions-saurabh-bhatia.aspx

    m.

  • Hi,

    I am building my VSTO 3.0 document level customization and using the content of the bin folder to load it at runtime with the "|vstolocal" option. However, when I resign the manifest with mage as described, the customization does not load with the following error message: Customized functionality in this application will not work because the certificate used to sign the deployment manifest for Design.TaskPane is not trusted.

    I have put the new cert in both the Trusted Root Certification Authorities and the Trusted Publishers cert store of the current user.

    Can you tell me what's the problem here? You can contact me offline at es(at)rubicon-it.com as well.

    Best regards,

    Ernst

  • Ernst,

    for document-level customizations, there is one extra step to trust the VSTO solution: the document location must be trusted in the Office application's trust center. for more information, see http://msdn.microsoft.com/en-us/library/bb772072(VS.100).aspx

    m.

  • Hi,

    that was not the problem. The issue was that resigning a VSTO manifest with a new cert does not work correctly because the publisher identity is not corrected to the new cert's identity.

    Best regards,

    Ernst

  • I am building VSTO 3.0 document-level customizations, signed the LeapDocEditor.dll.manifest and LeapDocEditor.vsto using mege.

    my document-level customizations has dependency such as custom.dotm template and dependency files (few configuration XML files).

    1. does mege add the hash value into manifest/VSTO for dependency custom.dotm and configuration XML files? if yes.

    2. does VSTO application verify the dependency files hash value when users launch the document-level customizations template?

    3. Does MS Word Prompt/disable if any files modified? (e.g. if signed/installed file replace with other dll/modified custom.dotm / modified configuration XML files).

    please advice, how to secure my dependency files by singing the  VSTO deployment.

    Best regards,

    Din

  • 1. does mege add the hash value into manifest/VSTO for dependency custom.dotm and configuration XML files? if yes.

    >>> No on the dotm file yes on the XML file. The dotm file is not included in the manifest and the XML file will be included in the manifest, when you use mage to update the manifest it should update the hash of the xml file.

    2. does VSTO application verify the dependency files hash value when users launch the document-level customizations template?

    >>> yes it verifies the file hash of all application files. Note the document itself is not a application file- Vsto will not download the application file itself and hence its hash is not verified.

    3. Does MS Word Prompt/disable if any files modified? (e.g. if signed/installed file replace with other dll/modified custom.dotm / modified configuration XML files).

    >>> I am not sure what the question is here I am assuming you are asking what happens if one of the files change and the hashes dont match anymore-> You will still see the initial trust prompt but you will not be able to install the solution, you will get an exception if you try to install a solution that has files whose hashes do not match up.

  • Hi,

    While I was updating the application manifest I was getting file not found error. I have got clear idea of the clickonce deployment. Thanks a lot.

  • Hello,

    I am looking for documentation on how all the digest values are calculated by mage tool. Clearly the manifests follow the XML signing specification, but I could not find any material on what goes into the digest value inside the Reference elements.

    According to the spec, if the URI attributed inside the <Reference ...> element is empty, the source of resource for which the digest is being calculated is internally known to the application (in this case mage.exe). This information would allow people to contribute other platform independent solutions for manifest generation and signing.

    Would it be possible to get a clear explanation on how these manifest files can be generated using standard technologies on platforms other than Windows?

  • hi Rob,

    you can use the following example to calculate the digest value by using the SHA1 method, but theoretically, you can use any of the cryptography methods.

    FileInfo fi = new FileInfo("FullPathToManifestFile");

    Stream s = null;

    s = fi.OpenRead();

    SHA1Managed sha = new SHA1Managed();

    byte[] hashBytes = sha.ComputeHash(s);

    string hash = Convert.ToBase64String(hashBytes);

    Console.WriteLine("hash for manifest: " + hash);

    on non-Windows platforms, perhaps you can use Mono and the System.Security.Cryptography namespace.

    m.

  • Thanks for your reply. Coincidentally I just downloaded mono today and found the class you mentioned. Thank you.

    -Rob

  • Hi,

    I have some troubles with resigning using above mentioned way (and it is the preferred way) using mage.exe, but no problem with MageUI.exe.

    After some investigations I found that the <publisherIdentity> element of manifest files is not overwriting by mage.exe, so users get prompts saying unknown publisher and machine access warning (after installing all the certificates).

    Similarly I tested using "SecurityUtilities.SignFile(..)" method same situation occurred, that method is not overwritingan existing <publisherIdentity> element, but it can write that element if it is not existing.

    Any idea about this scenario?

    Thanks.

Page 1 of 2 (23 items) 12

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