Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

http add sslcert fails when done programmatically

Tags:

c#

ssl

I have developed a self-hosted api.

The api traffic needs to run over SSL.

Using a combination of netsh commands I have managed to successfully add the certificate and then bind a route to my service. Happy Days.

But, I have to write an installer to do this programmatically.

The problem is that when I add the certificate using my c# code, I can see it the certificate MMC but when I try to bind to it I get an error of:

SSL Certificate add failed, Error: 1312
A specified log-on session does not exist. It may already have been terminated.

As I say, when I do it manually with these steps I don't get the problem...

  1. List item
  2. Double click on the .pfx file.
  3. MMC opens.
  4. I select "Local Machine"
  5. On the next screen I confirm the .pfx file location and name.
  6. I enter the password for the certificate and select "Include all extended properties"
  7. On the next screen I let it default to "Automatically select the certificate store based on the type of certificate"
  8. I then get a confirmation screen.
  9. When I click "Finish" I get a message "The import was successful"

I can then see it in MMC under Personal > Certificates

And it lets me add the route using netsh from a command prompt - Happy Days.

When I try an do it programmatically with the following code:

public static bool ConfigureSSLCertificate(string file, string password, string method)
    {
        try
        {
            X509Certificate2 cert = new X509Certificate2(file, password);

            var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadWrite);
            if (!store.Certificates.Contains(cert))
            {
                if (method == "add")
                {
                    store.Add(cert);
                }
            }
            if (method == "remove")
            {
                store.Remove(cert);
            }
            return true;
        }
        catch { return false; }
    }

The certificate appears in my MMC in exactly the same place but when I try and add the route with the exact same netsh command as before I get the error mentioned above:

netsh>http add sslcert ipport=0.0.0.0:8088 certhash=fb93ce2c4d8bd88c82e63e3372a050ba84f15e94 appid={bb14356a-a14f-4589-82ce-b80d38b8741e}

For some reason, when I add the certificate manually using the MMC and when I run my code something is different. Something that is stopping the route being added.

like image 269
Trevor Daniel Avatar asked Nov 10 '22 06:11

Trevor Daniel


1 Answers

The solution is actually simple - I too have struggled with this, and have now found the solution. How can a manually added certificate differ from the programatically added one? Well, the short answer is to change your certificate load line to this:

X509Certificate2 cert = new X509Certificate2(file, password, X509KeyStorageFlags.MachineKeySet);

The key being that last parameter, which tells the certificate to save the private key stored in the machine location, and not the user location. Then the netsh command can find the private key, and can work.

The solution was found in the explanatory text by Paul Stovell and some digging to see how I could set that flag when loading the certificate into the store.

Now, why I can't programmatically do the netsh function is another matter...

like image 167
mj2008 Avatar answered Dec 03 '22 22:12

mj2008