简体   繁体   中英

Certificate Detection/Installation with WiX Installer

Using WiX, is there a way to detect if a Certificate is installed on a machine? Is the only option you have to run a custom action with C# to detect if the certificate is installed, or is there a built in way with WiX to do it. I know how to install a certificate with WiX, but there needs to be some custom logic to detect if it already exists.

For example...

Our installer is a Per-User install, which means we don't have write access to the local-machine certificate store (although we do have read access). I have the following component in my .wxs file that adds the certificate to the User Certificates store:

  <Component Id="C__IntermediateCert" Guid="{GUID_HERE}" Permanent="no" >
    <iis:Certificate Id="_IntermediateCert" BinaryKey="B__IntermediateCert" StoreName="ca" Overwrite="no"
         StoreLocation="currentUser" Name="Intermediate Cert Name" Request="no" />
  </Component>

The problem is that this line will fail if there is already a certificate with this name in the local machine certificate store, even though we specified overwrite=no. There is an installer error raised and the user cannot continue the installation.

So the workaround I want to implement is to first look to see if the certificate is installed on the machine (either in local machine or user) and skip the component if it is already installed. However, it doesn't appear there is anyway to just search for the certificate (like there is for files/directories).

Any suggestions or help with how to either search for the certificate, or point out what I am doing wrong in the certificate creation (to properly ignore if it is already installed) would be greatly appreciated!

EDIT: (with correct solution)

Adding some information about a workaround I tried, and is now working. I ended up creating a C# custom action that should check if the certificate exists

See here:

    public static ActionResult CheckForExistingCertificate(Session session)
    {
        session.Log("Starting CheckForExistingCertificate");

        try
        {
            session.Log("***** Beginning LocalMachine Certificate Store Search...");
            X509Store lmStore = new X509Store(StoreName.CertificateAuthority, StoreLocation.LocalMachine);
            lmStore.Open(OpenFlags.ReadOnly);
            session.Log("***** lmStore.Certificates.Count = " + lmStore.Certificates.Count);
            foreach(X509Certificate2 cert in lmStore.Certificates)
            {
                session.Log("lmCertificate Listing : " + cert.FriendlyName);
                if (cert.FriendlyName == "Intermediate Cert Name")
                {
                    session["INTERMEDIATECERTIFICATEALREADYINSTALLED"] = "TRUE";
                }
            }

            session.Log("***** Beginning CurrentUser Certificate Store Search...");
            X509Store cuStore = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser);
            cuStore.Open(OpenFlags.ReadOnly);
            session.Log("***** cuStore.Certificates.Count = " + cuStore.Certificates.Count);
            foreach (X509Certificate2 cert in cuStore.Certificates)
            {
                session.Log("cuCertificate Listing : " + cert.FriendlyName);
                if (cert.FriendlyName == "Intermediate Cert Name")
                {
                    session["INTERMEDIATECERTIFICATEALREADYINSTALLED"] = "TRUE";
                }
            }

        }
        catch
        {
            session.Log("CheckForExistingCertificate - in catch");
        }

        session.Log("Ending CheckForExistingCertificate - end of function");
        return ActionResult.Success;
    }

Interesting, I hit the exact same bug last week. I was really up against a deadline so I just wrote a custom action to delete the certificate if it exists and the component is being reinstalled. But yes, I believe this is a WiX 3.8 bug as If overwrite=no it shouldn't cause a problem.

In my case we were distributing a cert via group policy and via an MSI to ensure we had as close to 100% coverage as possible. The MSI worked and the GPO worked but then the MSI failed after the GPO was applied. I delete the GPO loaded cert, load mine and then when you do a GPUPDATE -FORCE you end up with two copies of the cert but with no obvious negative side effects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM