Configuring ClickOnce Trusted Publishers
Visual Studio 2005
Summary: ClickOnce security allows you to take advantage of the runtime security protections provided by Code Access Security, while still allowing a dynamic determination of permissions for a particular application at the point where the application is deployed through ClickOnce. (11 printed pages)
Trusted Publishers and ClickOnce Application Signing 101
ClickOnce Security Checks at Launch
Get Into the Zone
ClickOnce Trusted Publishers in Action
Automating the Process
About the Author
ClickOnce security allows the automatic elevation of privileges for a ClickOnce-deployed application based on either user prompting or trusted publishers. When you deploy an application with ClickOnce, the operations that application performs or the resources it tries to access may require Code Access Security (CAS) permissions greater than what it would be granted based on the current policy. If that is the case, by default the .NET Framework runtime on the client machine will prompt the user and ask them whether they want to install the application and grant it elevated trust.
In an enterprise environment where administrators own the desktop and configuration control over each desktop is possible, it is generally preferable to avoid having to prompt the user for trust decisions. Most users do not have the sophistication to understand the implications of their trust decisions, and do not know when they should or should not grant application permissions. ClickOnce gives you control over this problem by allowing ClickOnce applications to automatically elevate their own privileges without user prompting—if the application manifests have been signed by a trusted publisher.
So what constitutes a trusted publisher? First, you must always sign the ClickOnce deployment and application manifests with a publisher certificate. Next, the certificate used to sign a ClickOnce application must be configured in the Trusted Publishers certificate store on the user's machine. And finally, the certificate authority that issued the certificate must be configured in the Trusted Root Certificate Authority certificate store on the user's machine. I'll peel back the layers of each of these three pieces in turn.
When you first create a Windows Forms application in Visual Studio 2005 and publish it with ClickOnce, Visual Studio will automatically generate a publisher certificate for you and use it to sign your application when it is published. When it does this, it generates a personal certificate file (.pfx file) and adds it to your Visual Studio project with a default file naming convention of <ProjectName>_TemporaryKey.pfx. Visual Studio will also add this certificate to your personal certificate store, and will enable the project settings that set this certificate as the one to be used to sign ClickOnce application manifests. Because this all happens automatically, you might not even be aware it is occurring.
Note Beta 1 allowed you to strong name your manifests using a strong name key file (.snk file by convention). Beta 2 and RTM no longer support this, and you must sign your manifests with a publisher certificate, typically a .pfx file that may or may not be password protected.
The signing process uses the public and private keys in the certificate to apply an XML Digital Signature to the deployment and application XML manifest files generated for a ClickOnce application. This digital signature approach ensures that you know who signed a given ClickOnce application deployment based on the public key that gets embedded in the manifest file, and that the file has not been tampered with or its contents changed in any way since it was signed. This prevents a malicious party from adding unintended settings or files to a ClickOnce application after it is published by a trusted authority.
Publisher certificates come in two flavors—self-generated or third-party–verified (by Verisign, for example). A certificate is issued by a certificate authority, which itself has a certificate that identifies it as a certificate issuing authority. A self-generated certificate is one that you create for development purposes, and you basically become both the certificate authority and the publisher that the certificate represents. To be used for production purposes, you should be using a certificate generated by a third party, either an external company like Verisign or an internal authority such as your domain administrator in an enterprise environment.
To be considered a trusted publisher, the publisher certificate must be installed in the Trusted Publishers certificate store on the user's machine, and the issuing authority of the publisher certificate must have their own certificate installed in the Trusted Root Certification Authority certificate store. You can use the certmgr.exe certificate management console in Windows to manage and install certificates in the stores on your machine, and you can also install them using Visual Studio 2005. I'll step you through the process of using Visual Studio later in this article.
When a ClickOnce application is being launched on a user's desktop the first time, the .NET Framework runtime will first check to ensure that the application manifests have not been tampered with since they were signed with whatever publisher certificate was used for signing. If they pass that check, the runtime will then look into the Trusted Root Certification Authority store and see if the certificate for the issuer of the publisher's certificate is installed in that store. It will then look at who the publisher on the certificate is, and see if their certificate is in the Trusted Publishers store. If those two things are true, then by default the user will not be prompted, and the application will be granted whatever privileges are specified in the application manifest file. An application trust for this application will be added to the user's .NET Framework security policy, the app will then just launch and run, and if the permissions were specified correctly in the application manifest, the user should never see a prompt or a security exception.
If both the issuer of the certificate and the publisher represented by the certificate are unknown on the client machine (based on the certificates installed in the stores), then the user will be prompted with the dialog box shown in Figure 1 and they can decide whether to allow the application to obtain the required privileges, depending on which zone the application is being launched from. If they click on the More Information... link at the bottom, they will get the dialog box shown in Figure 2, which gives the user a little more detail on what is about to happen if they click the Install button, but in general is probably just going to scare them—like most security dialogs do—because it gives very little information about what is really going on.
Figure 1. Untrusted publisher and certificate authority user prompt
Figure 2. More Information dialog
If the certificate used to sign the application manifests is generated by a trusted root certificate authority, but the specific publisher certificate is not in the trusted publishers store, then the user will still be prompted, but with a slightly friendlier prompt than when the issuer of the publisher certificate is unknown (see Figure 3). The more friendly prompt will indicate the publisher organization, because with the Authenticode certificate technology and trusted roots, you can at least trust that the publishing organization is who they say they are according to the issuer of the certificate. If you trust the issuing authority, then you can trust that the publisher is not pretending to be someone they are not.
Figure 3. Trusted certificate authority user prompt
After an application trust has been created for a given application, either due to automatic configuration based on a trusted publisher certificate, or based on the user being prompted and allowing the application to install, subsequent versions of the same application will not need to prompt again unless the requested security permissions change.
There are five built-in security zones that are used in CAS for origin-based trust decisions: MyComputer, LocalIntranet, Internet, TrustedSites, and UntrustedSites. These same zones are used to determine what kind of prompting should be allowed for users with respect to elevating ClickOnce application permissions. Each zone corresponds to the context from which a ClickOnce application is launched, which is determined by the full path address that was used to the deployment manifest (.application file) for the ClickOnce application.
Table 1 shows some examples of launch zones based on the address used for the deployment manifest. What it basically breaks down to is if the address is a local file path to a non-networked drive, the application will be launched in the MyComputer zone. If the address uses a network protocol (http or UNC file share) and the server portion of the address is a single machine name, it will be evaluated to be coming from the LocalIntranet zone. If the server name portion of the address contains dots, it is evaluated as coming from the Internet zone. TrustedSites and UntrustedSites depends on individual addresses that are configured as part of Internet Explorer's Trusted Sites and Restricted Sites security settings.
Table 1. ClickOnce Launch Zone Examples
|Launch Address||Launch Zone|
By default, the MyComputer, LocalIntranet, and TrustedSites are configured to allow user prompting to elevate security privileges of a ClickOnce application if that application is not signed by a trusted publisher. The Internet zone default is that if the application manifest is signed by a publisher certificate issued by a trusted root authority, then that application can prompt the user for elevated permissions if needed (that is, the publisher certificate is not also installed in the Trusted Publishers store). If an Interne-launched application is not signed with a certificate issued by a trusted root authority, the application will not be allowed to run. The UntrustedSites zone default is that if the application is not signed by a trusted publisher certificate issued by a trusted root authority, the application will not be allowed to run (in other words, no user prompting is allowed).
These settings can be modified if desired for your enterprise by configuring an obscure registry key that will be checked by ClickOnce to determine the user prompting policy. Each of the behaviors described above corresponds to a value you can set for each of the zones through this registry key.
The registry key \HKLM\Software\Microsoft\.NETFramework\Security\TrustManager\PromptingLevel is the one that allows you to customize the prompting behavior. This key is not present by default after a .NET Framework 2.0 installation, so you will have to create it manually if you want to customize these settings.
Under that registry key, you can add any of 5 string values, named MyComputer, LocalIntranet, Internet, TrustedSites, and UntrustedSites. These correspond to their respective zones. As a value for these, you can set one of three strings: Enabled, Disabled, or AuthenticodeRequired. Enabled is the default for the MyComputer, LocalIntranet and TrustedSites zones. The Internet default is AuthenticodeRequired, and the UntrustedSites default is Disabled. Table 2 shows the values that you can set for each zone and their effects. Figure 4 shows the registry key values set to their default behavior, but keep in mind this key does not exist by default so you will typically only create it if you are going to set them to different values than the defaults.
Table 2. PromptingLevel Registry Key Value Launch Effects
|Value||Not Trusted Root Authority||Certificate Issued by Trusted Root Authority||Trusted Root Authority and Trusted Publisher Certificate|
|Enabled||Unfriendly user prompt||Friendly user prompt||No prompt; permissions granted and app launches|
|AuthenticodeRequired||Application disabled||Friendly user prompt||No prompt; permissions granted and app launches|
|Disabled||Application disabled||Application disabled||No prompt; permissions granted and app launches|
Figure 4. User Prompting Registry key values
To test this, you will need to configure certificates on your development machine. The first step is to have a certificate to use to sign your ClickOnce apps and to configure that certificate in the desired certificate stores on your development or test machine. As mentioned before, Visual Studio will generate a new certificate for each ClickOnce project unless you configure a certificate to use for signing ClickOnce manifests before you first publish the application. I recommend generating a new test certificate, saving it to a known location, and then using that to sign all of your developmental ClickOnce projects so that you don't have to litter up your certificate stores with a bunch of test certificates. The certificate that is automatically generated is not password protected, and I strongly recommend you only use certificate files that are password protected.
To generate a new certificate file in Visual Studio 2005 that is password protected, go to the project properties window (double-click on the Properties node in Solution Explorer, or right-click on the project node and select Properties from the context menu). Select the Signing tab, check the Sign the ClickOnce Manifests check box, and click the Create Test Certificate... button (see Figure 5). You will be prompted for a password, and a new pfx file with a default name will be added to your project. This certificate will also be set as the certificate used to sign the manifests, and it will be installed in your personal certificate store in Windows. You can then rename the file, copy it to a reusable location, and then configure that certificate as the cert for any application by pressing the Select From File... button in the Signing tab.
Figure 5. Signing project properties
Once you have a certificate and have identified which one to use for signing your ClickOnce manifests in the Signing project properties, you can publish your application from Visual Studio and the manifests will be signed with that certificate. If you happen to have a "real" publisher certificate (that is, a Verisign one, or one that your development organization uses signed by some other trusted root authority), you can use that instead, either from a file as described above, or by pointing to the certificate in your personal store of certificates using the Select From Store... button in the Signing project properties.
To see how you can avoid a user prompt with a trusted publisher deployment, you need to configure the publisher certificate on the machine where the app will be launched with ClickOnce, which is often your development machine for first trials and development purposes. If you generated the certificate yourself as described above (or using the makecert.exe command-line utility that comes with Visual Studio), you will need to add that certificate to the Trusted Root Certification Authorities store. This is because you are not only the publisher, but you are also the issuer of the certificate. You will then also want to install the same certificate into the Trusted Publishers store, which is the final step that allows the application to launch without prompting.
To make this all concrete, let's step through an example by the numbers. Start a new Windows Application project in Visual Studio 2005 and name it ClickOnceTrustedPub. After the project is created, go to the project properties by double-clicking the Properties node in the Solution Explorer tree under the project node, and select the Signing tab.
Next, select the box to Sign the ClickOnce manifests. Press the Create Test Certificate... button, and enter a password for the certificate. The file that will be created and added to the project will be named ClickOnceTrustedPub_TemporaryKey.pfx. Rename it to devcert.pfx in Solution Explorer. This would also be a good time to copy the file to some common development folder on your machine so that you can reuse it for subsequent projects and not have to keep regenerating and configuring your certificates. When creating the certificate file, Visual Studio also installed it in your Personal store of certificates.
To add this certificate to the Trusted Root Certificate Authority and Trusted Publisher stores, click on the More Details button in the Signing project properties tab. This brings up the certificate information dialog (see Figure 6). Click the Install Certificate... button at the bottom of the General tab, and you will be presented with the Certificate Import Wizard.
Figure 6. Certificate information dialog
In the second step of the wizard, select the radio button to Place all certificates in the following store, then press the Browse button (see Figure 7). This will open a dialog box where you can select from the list of certificate stores (see Figure 8).
Figure 7. Certificate Wizard store selection
Figure 8. Certificate Store selection dialog box
The first time through this process, select the Trusted Root Certificate Authorities store, click Next, and then Finish in the wizard. You will be prompted with a verbose security-warning dialog about the hazards of installing a root authority certificate. Go ahead and click Yes or you will not be able to try out the trusted publisher functionality of ClickOnce, but make sure you understand the risk that it is describing. If someone else obtained your certificate, signed an application with it, and then launched it on your machine, Windows would treat that application as having been published by a company that has been verified by a trusted authority.
Repeat the process described starting with the More Details button, but this time install the same certificate into the Trusted Publishers store.
Once you have done this, you can publish your application with ClickOnce. To do this, select Publish <ProjectName> from the Build menu in Visual Studio, and click Finish in the wizard that pops up. This will build your app, publish it with the default ClickOnce publishing settings, and will present you with a Web page from which you can test the installation as a client by clicking on the Install button on the Web page. If you click on that button, the application should download and run on the desktop without any form of prompting. The default permissions requested by a ClickOnce application are unrestricted (full trust), and the default Install button link presented uses a LocalIntranet zone URL. So if you repeated this same process without having configured the trusted publisher certificate, you would have been prompted with the dialog box shown in Figure 1.
In an operational environment with lots of user machines to maintain, you are not going to have Visual Studio available on each machine to configure publisher certificates, so you will need to use the certificate management console (certmgr.exe) included in Windows. If you just run certmgr.exe with no arguments from a command line, a Microsoft Management Console (MMC) window appears that will allow you to add or remove certificates from any of the stores on the local machine. But even with that, you may not want to have to go touch every machine to configure the certificates. The process can also be automated using certmgr.exe with some command-line parameters.
You first need to export the public portion of a certificate into a certificate file (.cer) from certmgr using the Export button:
Figure 9. Certmgr.exe exporting certificates
After you have done that, you can copy that certificate file to a target machine and run certmgr.exe on the command line. You will need to pass it the file name along with which store to place it in as command-line parameters with the appropriate switches, and that will install the certificate on the machine:
certmgr –add alice.cer –s Root certmgr –add alice.cer –s TrustedPublisher
All of this can be scripted or added to a custom installer through a Visual Studio Setup and Deployment project (or some other form of installer), and the resulting Windows Installer package (.msi file) can be added to the bootstrapper for your ClickOnce application. For more information on the bootstrapper, see Sean Draine's article Use the Visual Studio 2005 Bootstrapper to Kick-Start Your Installation in the October 2004 issue of MSDN Magazine.
ClickOnce security allows you to take advantage of the runtime security protections provided by Code Access Security, while still allowing a dynamic determination of permissions for a particular application at the point where the application is deployed through ClickOnce. However, this flexibility comes at a price—you have to decide whether to allow the user to be the one responsible for elevating application permissions through prompting, and whether you want that prompting to be based on where the publisher certificate came from. The default behavior of ClickOnce is the easiest to understand. Either an application is going to automatically elevate its permissions because it is being deployed from a trusted publisher, or it is going to prompt the user to let them decide whether to trust the publisher. In more controlled environments, you may want to restrict user prompting, and this article has spelled out how you can do that using the PromptingLevel registry key and configuring publisher and trusted root authority certificates on the user's machine. Understanding the effects of the various values and how they behave with different certificate store configurations is important to properly employing the security protections of ClickOnce.
About the Author
Brian Noyes is a Microsoft MVP and well-known speaker, trainer, writer, and consultant with IDesign, Inc. (www.idesign.net). He speaks at TechEd US and Malaysia, Visual Studio Connections, VSLive!, DevEssentials, and other conferences, and is one of the top-rated speakers on the INETA Speakers Bureau. He has published numerous articles on .NET Framework development for MSDN Magazine, Visual Studio Magazine, asp.netPRO, The Server Side .NET, CoDe Magazine, .NET Developer's Journal, and other publications. His latest book, Data Binding in Windows Forms 2.0, part of the Addison-Wesley .NET Development Series, will hit the shelves in the fall of 2005. Brian got started programming to stimulate his brain while flying F-14 Tomcats in the Navy, applying his skills and interest to programming aircraft and avionics simulations, prototypes, and support applications while stimulating his adrenal glands attending Top Gun and U.S. Naval Test Pilot School.