I had to integrate to a SOAP service in my current project which requires installing a PFX certificate. I want to install it in code during start up so that it will just work on other developers’ machines.
Here is the implementation of the function that installs the certificate. It requires the path to the certificate and the certificate password.
public void InstallX509Certificate(string certificateFileName, string certificatePassword)
{
using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
{
store.Open(OpenFlags.ReadWrite);
var certCollection = new X509Certificate2Collection();
certCollection.Import(certificateFileName, certificatePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
store.AddRange(certCollection);
store.Close();
}
}
Some issues
There was a few problems I ran into when I worked on this function. At the beginning, instead of using X509Certificate2Collection and then import, I add the certificate directly to the store. See below
public void InstallX509Certificate(string certificateFileName, string certificatePassword)
{
using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
{
store.Open(OpenFlags.ReadWrite);
store.Add(new X509Certificate2(certificateFileName, certificatePassword, X509KeyStorageFlags.Exportable));
store.Close();
}
}
The certificate was installed successfully but I found that when the SOAP requests were sent, the first request never had a response coming back. It was just lost. I had a breakpoint where it made the request and when I stepped over, there was no response. Any requests made after the first one had response coming back successfully.
I checked the installed certificate and compared it to the same one I installed manually. I find all the properties are the same however when I installed it manually, it installed 2 certificates (due to certification chain) but the code only installed one.
After lots of research, importing using X509Certificate2Collection installs the same number of certificates similarly to when I installed it manually. This however still did not solve the issue with the first request not getting back the response.
I then came across X509KeyStorageFlags.PersistKeySet from a Microsoft support page here. It basically said X509KeyStorageFlags.PersistKeySet should be used if installing PFX certificate. Without the flag,
creates a temporary container to import the private key. The private key is deleted when there is no longer a reference to the private key. The
PersistKeySet will prevent this. This solves the issue with the first request not getting back the response. However this does not explain why it worked after the first request.