Search code examples
c#.netbouncycastlex509certificatex509certificate2

How can i write in the "Enterprise Trust" Store?


I have a .p7b file with a few certificates and i want to install them in the "Enterprise Trust" Store. A program i want to use expects it there.

I have writte code in c# which extract all the certificates from the file and installs them into a X509Store ("Storename.My") which works.

If i try to use the same code to write in a different store it (which already exists) it creates a new empty store and writes in there.

The StoreName.My is taken from system.Security.Cryptography.X509Certificates public enum StoreName, but there is no option for the "Enterprise Trust" store. So i tried to use the constructor where i can give the StoreName as a string.

I use the certmgr from windows to check what certificats are stored in which stores.

// open file
var certificateStore = new CmsSignedData(new 
FileStream(_tempFileName.ToString(), FileMode.Open));

// get all certificats
IX509Store x509Certs = certificateStore.GetCertificates("Collection");
var a = new ArrayList(x509Certs.GetMatches(null));

// this works
var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); 

// this doesnt work
// var store = new X509Store("Enterprise Trust", StoreLocation.CurrentUser);

// open store
store.Open(OpenFlags.ReadWrite);

// write in store
foreach (object o in a) {
    var cert = (Org.BouncyCastle.X509.X509Certificate)o;
    var cert509 = new X509Certificate2();
    cert509.Import(cert.GetEncoded());
    store.Add(cert509);
}
store.Close();

How do i write correctly in the a store which isnt the StoreName enum?


Solution

  • If you want to be sure you aren't creating a new store, you can use the OpenFlags value OpenExistingOnly. Asserting that flag and checking for, e.g. "Trust2" yields System.Security.Cryptography.CryptographicException: The system cannot find the file specified. Therefore we get the best level of assurance that "Trust" is the right answer by specifying it as:

    using (X509Store store = new X509Store("Trust", StoreLocation.CurrentUser))
    {
        store.Open(OpenFlags.ReadWrite | OpenFlags.OpenExistingOnly);
        ...
    }
    

    (Note that this is less good to use on Linux (.NET Core), because only Windows pre-initializes the stores)

    We can get confirmation on the programmatic name to the display name via the certutil.exe command-line utility:

    >certutil -store trust
    trust "Enterprise Trust"
    CertUtil: -store command completed successfully.
    

    (I just don't have anything in that store)