none
How can I add Root and Intermediate Certificate to X509Store? RRS feed

  • Question

  • The following code runs without error, but Certificates.Add function has no effect, no certificate was added, why?

     

    Code Snippet

    public class Certificates
        {
            private static string targetDir;

            [StorePermission(SecurityAction.Demand, Flags = StorePermissionFlags.AddToStore)]
            public static void Import()
            {
                try
                {
                    StorePermission sp = new StorePermission(StorePermissionFlags.AddToStore);
                    sp.Demand();
                    targetDir = new DirectoryInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).Parent.FullName;
                    X509Store storeRoot = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
                    storeRoot.Open(OpenFlags.ReadWrite);
                    X509Certificate2 certRoot = new X509Certificate2(Path.Combine(targetDir, "Root.cer"));
                    bool certExist = false;
                    foreach (X509Certificate2 c in storeRoot.Certificates)
                    {
                        if (c.Subject == certRoot.Subject)
                        {
                            certExist = true;
                            break;
                        }
                    }
                    if (!certExist) storeRoot.Certificates.Add(certRoot);
                    storeRoot.Close();

                    X509Store storeIntermediate = new X509Store(StoreName.CertificateAuthority, StoreLocation.LocalMachine);
                    storeIntermediate.Open(OpenFlags.ReadWrite);
                    X509Certificate2 certIntermediate = new X509Certificate2(Path.Combine(targetDir, "Intermediate.cer"));
                    certExist = false;
                    foreach (X509Certificate2 c in storeIntermediate.Certificates)
                    {
                        if (c.Subject == certIntermediate.Subject)
                        {
                            certExist = true;
                            break;
                        }
                    }
                    if (!certExist) storeIntermediate.Certificates.Add(certIntermediate);
                    storeIntermediate.Close();
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
        }

     

     

    Thank you!
    Monday, April 21, 2008 9:49 AM

All replies

  • dotAge,

     

    Based on your post, the code snippet runs fine but the certificate cannot be added. Generally speaking, to import a certificate, you call the Add method on the X509Store instance. When you specify a store name that doesn't exist in the constructor of the store, a new container will be created. Here's how you would import a certificate in a file named alice.cer into a new container called Test:

     

    Code Snippet

            static void ImportCert()

            {

                X509Certificate2 cert = new X509Certificate2("alice.cer");

                X509Store store = new X509Store("Test", StoreLocation.CurrentUser);

                try

                {

                    store.Open(OpenFlags.ReadWrite);

                    store.Add(cert);

                }

                finally { store.Close(); }

            }

     

     

    As far as I've knwon, the best article on this topic is: Support Certificates In Your Applications With The .NET Framework 2.0 In this article, you can try the code snippet and section Searching for Certificates, Choosing Certificates and Validating Certificates.

     

    I hope this can provide you some idea. If there is any further problems, please feel free to let me know. Thanks in advance of your questions.

    Tuesday, April 22, 2008 6:19 AM
  • Hi, Bruno:

     

    The problem is that these two CAs(root and intermediate) are used by Background Intelligent Transfer Service(BITS) which runs as Local System account, so that the CAs need to be imported into machine-wide StoreLocation.LocalMachine. and need to place them into right container by their type. If else, BITS cannot works with HTTPS protocol, it failed by "0x80072f0d The certificate authority is invalid or incorrect".

    Because users always confused how to import them to right store place use MMC manually, so I am trying to import them automatically by code.

     

    Thanks again.

     

    Tuesday, April 22, 2008 9:07 AM
  • dotAge,

     

    How is your problem going? The BITS service is capable of targeting resources via the HTTPS protocol. HTTPS is just HTTP communication that occurs in an encrypted SSL/TLS channel. You can read the article Write Auto-Updating Apps with .NET and the Background Intelligent Transfer Service API to know more about the BITS issues.

     

    Except import the certificate by code, have you tried to import by using the PKI Health Tool or Certutil.exe as the article shows? In addition, KB 298138 shows you the way to move a certification authority to a different server. I hope it can provide you some idea from any other way.

    Wednesday, April 23, 2008 9:41 AM
  • My program is no problem if these two certificates are imported to right store.

    My proplem is how can I import them by .NetFramework code,  why the code list above is not working?

    Now, I have found a workaround, that is call CertMgr.Exe tool by System.Diagnostics.Process.Start(), the code function same as these two command:

    CertMgr -add root.cer -c -s -r LocalMachine Root

    CertMgr -add intermediate.cer -c -s -r LocalMachine CA

     

    Although these are working, I still wish that can be implemented by System.Security.Cryptography.X509Certificates class.

    Thursday, April 24, 2008 5:33 AM