October 18, 2010 11:30 AM by Daniel Chambers
Recently I managed to add an extra certificate store to Windows by mistake, as I accidentally left out a command line argument when using makecert. Unfortunately, the Certificates MMC snap-in doesn’t seem to provide a way for you to delete a certificate store, so I had resort to a more technical approach in order to get rid of this new unwanted certificate store.
Digging around in the Windows API, I found the CertUnregisterSystemStore function that allows you to delete a certificate store programmatically. So I spun up my copy of LINQPad so that I could quickly script in C# and PInvoke that function. (Incidentally, if you don’t have a copy of LINQPad and you’re a .NET developer, you need to get yourself a copy immediately. It’s invaluable.) Unfortunately, CertUnregisterSystemStore takes a flags parameter, and the actual values of the different flags are defined in C++ .h files, which are not available from C#. So I punched out a few PowerShell commands to search the .h files in the Windows SDK for those #define lines.
Once those flag values were found, deleting the store ended up being this small C# script in LINQPad that simply calls CertUnregisterSystemStore with the appropriate flags:
void Main() { int CERT_SYSTEM_STORE_LOCATION_SHIFT = 16; uint CERT_SYSTEM_STORE_CURRENT_USER_ID = 1; uint CERT_SYSTEM_STORE_LOCAL_MACHINE_ID = 2; uint CERT_STORE_DELETE_FLAG = 0x10; uint CERT_SYSTEM_STORE_CURRENT_USER = CERT_SYSTEM_STORE_CURRENT_USER_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT; uint CERT_SYSTEM_STORE_LOCAL_MACHINE = CERT_SYSTEM_STORE_LOCAL_MACHINE_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT; CertUnregisterSystemStore("TestCertificate.cer", CERT_STORE_DELETE_FLAG | CERT_SYSTEM_STORE_CURRENT_USER); } [DllImport("crypt32.dll", CharSet = CharSet.Unicode)] public static extern bool CertUnregisterSystemStore(string systemStore, uint flags);
I’ve also included the flags needed to delete stores from the local machine (as opposed to the current user account) in the script above, in case anyone ever needs to do that.
Submit Comment | Comments RSS Feed
Art
February 04, 2011 3:33 AM
This is exactly what I needed, as I ending up doing the same as you. I can't believe that there is no command-line tool provided by Microsoft which allows you to delete a store if you accidentally create one.
Thanks!
clau137
March 02, 2011 10:50 AM
Worked like a charm! Many many thanks! Tiny time saver: add namespace System.Runtime.InteropServices in Query Properties (F4)
Thanks!
August 30, 2011 6:09 AM
Thank you for pointing some of us in the right direction.
I have a question: Have you ever tried to remove/delete a certificate store from the local machine instead of current user?
I managed to delete certificate stores from the current user but never from the local machine. Curiously enough, the CertUnregisterSystemStore() call with (CERT_STORE_DELETE_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE) ends up successfully every single time but without any effect!
Michel I. Gallant (http://www.jensign.com/JavaScience/www/deletesystemstore/index.html) has a Java implementation where he seems to suggest that "Only deletion of CERT_SYSTEM_STORE_CURRENT_USER stores is enabled". I wonder if he refers to Windows or to his own program. MSDN does not state anything clearly in this matter.
Any comments are welcome.
August 30, 2011 6:29 AM
I'm sorry to say, but I'm definitely tired :-(
I had to run my little utility at an elevated administrative level in order to delete certificate stores from local machine.
Arghhh... I should have been aware of this (not the first time it happens).
Thanks for this wonderful blog and useful information.
Unknown (google)
August 01, 2013 10:29 AM
This is exactly what I was looking for over endless hours. Thanks for another five hours worth of sleep for me!