iisssl-certificatex509certificate2servermanager

System.Runtime.InteropServices.COMException: 'A specified logon session does not exist. It may already have been terminated


When trying to bind a cert to IIS im getting error "A specified logon session does not exist. It may already have been terminated" when committing the changes. I did notice the new cert im trying to bind says the Private Key is NOT exportable. Maybe thats why. Any ideas how to solve this error?

Code

private void Run(){
        
        dynamic certificates = JsonConvert.DeserializeObject(api.GetCertificates(_url_base, _username, _password));


        X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

         store.Open(OpenFlags.ReadWrite);

         X509Certificate2 renewedCert = X509Certificate2("c:\\fakeapppreview.gov.crt");

         X509Certificate2 tempCert = X509Certificate2.CreateFromPem(renewedCert.ExportCertificatePem(), store.Certificates[0].GetRSAPrivateKey().ExportRSAPrivateKeyPem());

         store.Add(tempCert);
         var _serverManager = new ServerManager();
         var site = _serverManager.Sites["apppreview"];

         site.Bindings.Clear();
         
         var binding = site.Bindings.Add("*:443:" + site.Name + ".gov", renewedCert.GetCertHash(), store.Name, SslFlags.Sni);
         
         binding.Protocol = "https";
         binding.CertificateHash = tempCert.GetCertHash();
         binding.CertificateStoreName = _serverManager.Sites["riskstaging"].Bindings[0].CertificateStoreName;
         binding.SetAttributeValue("certificateHash", tempCert.GetCertHashString());
         binding.SetAttributeValue("certificateStoreName", binding.CertificateStoreName);
 
         site.ServerAutoStart = true;
         _serverManager.CommitChanges();
         store.Close();
        
}

Solution

  • The answer was pretty straight forward. All i had to do was use the CopyWithPrivateKey() method to import the private key once I did that adding the binding worked smoothly with everything else.

    private void Run(){
            
            dynamic certificates = JsonConvert.DeserializeObject(api.GetCertificates(_url_base, _username, _password));
    
    
            X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
    
             store.Open(OpenFlags.ReadWrite);
    
             X509Certificate2 renewedCert = X509Certificate2("c:\\fakeapppreview.gov.crt");
    
             X509Certificate2 tempCert = renewedCert.CopyWithPrivateKey(store.Certificates[0].GetRSAPrivateKey());
    
             store.Add(tempCert);
             var _serverManager = new ServerManager();
             var site = _serverManager.Sites["apppreview"];
    
             site.Bindings.Clear();
             _serverManager.CommitChanges();
    
             _serverManager = new ServerManager();
             site = _serverManager.Sites["apppreview"];
             
             var binding = site.Bindings.Add("*:443:" + site.Name + ".gov", renewedCert.GetCertHash(), store.Name, SslFlags.Sni);
             
             binding.Protocol = "https";
             binding.CertificateHash = tempCert.GetCertHash();
             binding.CertificateStoreName = _serverManager.Sites["apppreview"].Bindings[0].CertificateStoreName;
             binding.SetAttributeValue("certificateHash", tempCert.GetCertHashString());
             binding.SetAttributeValue("certificateStoreName", binding.CertificateStoreName);
     
             _serverManager.CommitChanges();
             store.Close();
            
    }