When you need to grab a certificate out of a Windows Certificate Store, you can use a class called X509Store. It's very simple to use:
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection myCerts = store.Certificates.Find(X509FindType.FindByThumbprint, "...", false);
store.Close();
However, I don't like this open/close mechanism. It reminds me too much of Dispose(), except I can't use a using statement. There are lots of arguments around whether a using statement is a good way of doing things and I'm in the camp of yes, it is. When they are used properly they make code a lot more logical. It creates a scope for an object explicitly. I want to do something like this:
using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser, OpenFlags.ReadOnly))
{
X509Certificate2Collection myCerts = store.Certificates.Find(X509FindType.FindByThumbprint, "...", false);
}
The simple solution would be to subclass this, implement IDisposable, and overwrite some of the internals. The problem though is that someone on the .NET team thought it would be wise to seal the class. Crap. Okay, lets create a new class:
public class X509Store2 : IDisposable
{
private X509Store store;
public X509Store2(IntPtr storeHandle, OpenFlags flags)
{
store = new X509Store(storeHandle);
store.Open(flags);
}
public X509Store2(StoreLocation storeLocation, OpenFlags flags)
{
store = new X509Store(storeLocation);
store.Open(flags);
}
public X509Store2(StoreName storeName, OpenFlags flags)
{
store = new X509Store(storeName);
store.Open(flags);
}
public X509Store2(string storeName, OpenFlags flags)
{
store = new X509Store(storeName);
store.Open(flags);
}
public X509Store2(StoreName storeName, StoreLocation storeLocation, OpenFlags flags)
{
store = new X509Store(storeName, storeLocation);
store.Open(flags);
}
public X509Store2(string storeName, StoreLocation storeLocation, OpenFlags flags)
{
store = new X509Store(storeName, storeLocation);
store.Open(flags);
}
public X509Certificate2Collection Certificates { get { return store.Certificates; } }
public StoreLocation Location { get { return store.Location; } }
public string Name { get { return store.Name; } }
public IntPtr StoreHandle { get { return store.StoreHandle; } }
public void Add(X509Certificate2 certificate)
{
store.Add(certificate);
}
public void AddRange(X509Certificate2Collection certificates)
{
store.AddRange(certificates);
}
private void Close()
{
store.Close();
}
private void Open(OpenFlags flags)
{
store.Open(flags);
}
public void Remove(X509Certificate2 certificate)
{
store.Remove(certificate);
}
public void RemoveRange(X509Certificate2Collection certificates)
{
store.RemoveRange(certificates);
}
public void Dispose()
{
this.Close();
}
}
At this point I've copied all the public members of the X509Store class and called their counterparts in the store. I've also set Open() and Close() to private so they can't be called. In theory I could just remove them, but I didn't.
Enjoy!