You receive an error message when you try to update a Visual Studio 2005 ClickOnce application after the certificate that was used to sign the installation expires

Article translations Article translations
Article ID: 925521 - View products that this article applies to.
Expand all | Collapse all

On This Page

SYMPTOMS

When you try to update a Microsoft Visual Studio 2005 ClickOnce application after the certificate that you used to sign the installation expires, you receive the following error message:
The deployment identity does not match the subscription.

CAUSE

This problem occurs because you must sign all ClickOnce deployments by using a digital certificate. You cannot use an expired certificate to sign a ClickOnce application. To deploy an update to an application that has an expired certificate, you must assign the application a new certificate. When the new certificate does not match the original certificate, you receive the error message that is mentioned in the "Symptoms" section.

RESOLUTION

To resolve this problem, use one of the following methods.

Method 1

Update the client computer where the ClickOnce application is installed to the Microsoft .NET Framework 2.0 Service Pack 1 (SP1) or a later version.

Windows Vista

Apply the .NET Framework 3.5 or the .NET Framework 3.5 SP 1.

Note The .NET Framework 3.5 contains many new features that build incrementally upon the .NET Framework 2.0 and 3.0. The .NET Framework 3.5 includes the .NET Framework 2.0 SP1 and the .NET Framework 3.0 SP1.

The following file is available for download from the Microsoft Download Center:

Collapse this imageExpand this image
Download
Download the .NET Framework 3.5 package now.

Collapse this imageExpand this image
Download
Download the .NET Framework 3.5 Service Pack 1 package now.

For more information about how to download Microsoft support files, click the following article number to view the article in the Microsoft Knowledge Base:
119591 How to obtain Microsoft support files from online services
Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help prevent any unauthorized changes to the file.

Windows XP

Apply the .NET Framework 2.0 SP1 or the .NET Framework 2.0 Service Pack 2 (SP2).

The following files are available for download from the Microsoft Download Center:

Collapse this imageExpand this image
Download
Download the .NET Framework 2.0 Service Pack 1 (x86) package now.

Collapse this imageExpand this image
Download
Download the .NET Framework 2.0 Service Pack 1 (x64) package now.

Collapse this imageExpand this image
Download
Download the .NET Framework 2.0 Service Pack 2 package now.

For more information about how to download Microsoft support files, click the following article number to view the article in the Microsoft Knowledge Base:
119591 How to obtain Microsoft support files from online services
Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help prevent any unauthorized changes to the file.

Method 2

Uninstall the ClickOnce application that you signed by using the expired certificate. Then, reinstall the updated ClickOnce application that uses the new certificate.

Method 3

Create a command-line assembly that updates the certificate. To do this, follow these steps.

Microsoft provides programming examples for illustration only, without warranty either expressed or implied. This includes, but is not limited to, the implied warranties of merchantability or fitness for a particular purpose. This article assumes that you are familiar with the programming language that is being demonstrated and with the tools that are used to create and to debug procedures. Microsoft support engineers can help explain the functionality of a particular procedure. However, they will not modify these examples to provide added functionality or construct procedures to meet your specific requirements.
  1. In Visual Studio 2005, click New on the File menu, and then click Project.
  2. Click Visual C++, click Win32 Console Application, type RenewCert in the Name box, and then click OK.
  3. In the Win32 Application Wizard dialog box, click Finish.
  4. In the RenewCert.cpp file, replace the existing code with the following code:
    #include "stdafx.h"
    
    void ReadPFXFile(LPCWSTR fileName, CRYPT_DATA_BLOB *pPFX)
    
    {
    
                HANDLE hCertFile = NULL;
    
                DWORD cbRead = 0;
    
                DWORD dwFileSize = 0, dwFileSizeHi = 0;
    
                hCertFile = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    
                dwFileSize = GetFileSize(hCertFile, &dwFileSizeHi);
    
                pPFX->pbData = (BYTE *) CryptMemAlloc(dwFileSize*sizeof(BYTE));
    
                pPFX->cbData = dwFileSize;
    
                ReadFile(hCertFile, pPFX->pbData, pPFX->cbData, &cbRead, NULL);
    
                CloseHandle(hCertFile);
    
    }
    
    void GetPrivateKey(CRYPT_DATA_BLOB pPFX, LPCWSTR szPassword, HCRYPTPROV *hCPContext)
    
    {
    
                HCERTSTORE hCertStore = NULL;
    
                PCCERT_CONTEXT hCertContext = NULL;
    
                DWORD dwKeySpec = AT_SIGNATURE;
    
                BOOL bFreeCertKey = TRUE;
    
                hCertStore = PFXImportCertStore(&pPFX, szPassword, CRYPT_EXPORTABLE);
    
                hCertContext = CertEnumCertificatesInStore(hCertStore, NULL);
    
                CryptAcquireCertificatePrivateKey(hCertContext, 0, NULL, hCPContext, &dwKeySpec, &bFreeCertKey);
    
                CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
    
    }
    
    void PrintContainerName(HCRYPTPROV hCPContext)
    
    {
    
                DWORD containerNameLen = 0;
    
                CHAR *szContainerName = NULL;
    
                CryptGetProvParam(hCPContext, PP_CONTAINER, NULL, &containerNameLen, 0);
    
                szContainerName = (CHAR *)CryptMemAlloc(sizeof(BYTE)*containerNameLen);
    
                CryptGetProvParam(hCPContext, PP_CONTAINER, (BYTE *)szContainerName, &containerNameLen, 0);
    
                printf("This certificate's container name is: %s", szContainerName);
    
    }
    
    void MakeNewCert(HCRYPTPROV hCPContext, LPCWSTR szCertName, LPCWSTR szPassword, CRYPT_DATA_BLOB *pPFX)
    
    {
    
                CERT_NAME_BLOB certNameBlob = {0,NULL};
    
                PCCERT_CONTEXT hCertContext = NULL;
    
                SYSTEMTIME certExpireDate;
    
                HCERTSTORE hTempStore = NULL;
    
                CertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, szCertName, CERT_OID_NAME_STR, NULL, NULL, &certNameBlob.cbData, NULL);
    
                certNameBlob.pbData = (BYTE *)CryptMemAlloc(sizeof(BYTE)*certNameBlob.cbData);
    
                CertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, szCertName, CERT_OID_NAME_STR, NULL, certNameBlob.pbData, &certNameBlob.cbData, NULL);
    
                GetSystemTime(&certExpireDate);
    
                certExpireDate.wYear += 5;
    
                hCertContext = CertCreateSelfSignCertificate(hCPContext, &certNameBlob, 0, NULL, NULL, NULL, &certExpireDate, NULL);
    
                hTempStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, CERT_STORE_CREATE_NEW_FLAG, 0);
    
                CertAddCertificateContextToStore(hTempStore, hCertContext, CERT_STORE_ADD_NEW, NULL);
    
                PFXExportCertStoreEx(hTempStore, pPFX, szPassword, NULL, EXPORT_PRIVATE_KEYS);
    
                pPFX->pbData = (BYTE *)CryptMemAlloc(sizeof(BYTE)*pPFX->cbData);
    
                PFXExportCertStoreEx(hTempStore, pPFX, szPassword, NULL, EXPORT_PRIVATE_KEYS);
    
                CryptMemFree(certNameBlob.pbData);
    
                CertCloseStore(hTempStore, CERT_CLOSE_STORE_FORCE_FLAG);
    
                CertFreeCertificateContext(hCertContext);
    
    }
    
    void WritePFX(CRYPT_DATA_BLOB pPFX, LPCWSTR szOutputFile)
    
    {
    
                HANDLE hOutputFile = NULL;
    
                DWORD cbWritten = 0;
    
                hOutputFile = CreateFile(szOutputFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    
                WriteFile(hOutputFile, pPFX.pbData, pPFX.cbData, &cbWritten, NULL);
    
                CloseHandle(hOutputFile);
    
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    
    {
    
                LPCWSTR szCertFileName = NULL;
    
                CRYPT_DATA_BLOB pPFX;
    
                LPCWSTR szPassword = NULL;
    
                HCRYPTPROV hCPContext = NULL;
    
                LPCWSTR szCertName = L"CN=NewCert";
    
                CRYPT_DATA_BLOB pPfxOutputBlob = {0,NULL};
    
                LPCWSTR szOutFile = NULL;
    
                // Parse the command line.
    
                if(argc == 1)
    
                {
    
                            printf("renewcert <PFX File> <new cert filename> <new cert friendly name> [optional]<password>\n");
    
                            printf("Example: renewcert oldcert.pfx newcert.pfx \"CN=MyNewCert\" MySuperSecretPassword");
    
                            return 0;
    
                }
    
                if(argc >= 2)
    
                            szCertFileName = argv[1];
    
                if(argc >= 5)
    
                            szPassword = argv[4];
    
                // Uncomment this block to add <new cert filename> and <new cert friendly name> as parameters
    
                // NOTE: <new cert friendly name> must be of format "CN=<name>"
    
                if(argc >= 3)
    
                            szOutFile = argv[2];
    
                if(argc >= 4)
    
                            szCertName = argv[3];
    
                ReadPFXFile(szCertFileName, &pPFX);
    
                GetPrivateKey(pPFX, szPassword, &hCPContext);
    
                //PrintContainerName(hCPContext);
    
                // Uncomment this section to make a new PFX rather than just printing the container name.
    
                // Make sure you also uncomment the command line parameter section above.
    
                MakeNewCert(hCPContext, szCertName, szPassword, &pPfxOutputBlob);
    
                WritePFX(pPfxOutputBlob, szOutFile);
    
                // Clean up.
    
                CryptReleaseContext(hCPContext, 0);
    
                CryptMemFree(pPfxOutputBlob.pbData);
    
                CryptMemFree(pPFX.pbData);
    
                return 0;
    
    }
    
  5. In the stdafx.h file, replace the existing code with the following code:
    // stdafx.h : include file for standard system include files,
    
    // or project specific include files that are used frequently, but
    
    // are changed infrequently.
    
    //
    
    #pragma once
    
    #define WIN32_LEAN_AND_MEAN                     // Exclude rarely used material from Windows headers.
    
    #include <stdio.h>
    
    #include <tchar.h>
    
    #include <windows.h>
    
    #include <wincrypt.h>
    
  6. On the Project menu, click Properties to open the property pages for this project.
  7. Expand the Linker node, and then click Input.
  8. Click in the blank window to the right of Additional Dependencies, and then click the ellipsis button (...) to open to the Additional Dependencies dialog box.
  9. In the blank window, type Crypt32.lib, and then click OK.
  10. Click Apply, and then click OK to close the property pages.
  11. On the Build menu, click Build Solution.
  12. After the solution is built, execute the following command to update the certificate:
    renewcert <OldCertificate>.pfx <NewCertificate>.pfx \"CN=<NewCertificateName>\" <Password>
    Note <OldCertificate> is a placeholder for the old certificate, <NewCertificate> is a placeholder for the new certificate, <NewCertificateName> is a placeholder for the name of the new certificate, and <Password> is a placeholder for the password.

MORE INFORMATION

Steps to reproduce this problem

  1. Start Visual Studio 2005.
  2. On the File menu, click New, and then click Project.
  3. Click Visual C#, click Windows Application, type WindowsApplication1 in the Name box, and then click OK.
  4. In Solution Explorer, right-click WindowsApplication1, and then click Properties.
  5. Click Signing, and then assign a certificate that expires soon.
  6. In Solution Explorer, right-click WindowsApplication1, and then click Publish. The Publish wizard starts.
  7. On the Where do you want to publish the application? page, type a valid URL, and then click Next. Use the following format for the URL:
    http://ServerName/FolderName
  8. On the Will the application be available offline? page, click the appropriate option.

    Notes
    • If you want to let the user run the application when the user is disconnected from the network, click Yes, this application will be available online or offline. The wizard creates a shortcut for the application on the Start menu.
    • If you want to run the application directly from the publish location, click No, this application is only available online. The wizard does not create a shortcut on the Start menu.
  9. Click Next to continue.
  10. Click Finish to publish the application.
  11. Install the ClickOnce application from the http://ServerName/FolderName/publish.htm URL.
  12. After the certificate expires, repeat steps 6 to 10 to republish the application.
  13. Try to install the ClickOnce application update from the http://ServerName/FolderName/publish.htm URL.

Properties

Article ID: 925521 - Last Review: March 12, 2009 - Revision: 4.1
APPLIES TO
  • Microsoft Visual Studio 2005 Standard Edition
  • Microsoft Visual Studio 2005 Professional Edition
  • Microsoft Visual Studio 2005 Express Edition
Keywords: 
kbtshoot kberrmsg kbbug kbprb KB925521

Give Feedback

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com