John Hennesey
John Hennesey

Reputation: 375

List SSL certificates in c# (recreate IIS bindings dialog)

I am trying to list the SSL certs listed in the IIS bindings dialog box - but am unable to. I'm dancing all around it, can anybody tell me where they are stored? (My code snipped below isn't a 1:1 match - I can't figure out what store they are in).

enter image description here

X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
foreach (var x in store.Certificates)
{
     radDropDownListIISCert.Items.Add(new RadListDataItem(x.FriendlyName, x.SerialNumber));
}

Upvotes: 1

Views: 1161

Answers (3)

Konop
Konop

Reputation: 46

All answers return more certificates than IIS binding dialog. I've compared the differences between certificates that are and aren't shown. The difference seems to be EnhancedKeyUsageList : {Server Authentication (1.3.6.1.5.5.7.3.1)} - for those that are shown and EnhancedKeyUsageList : {Client Authentication (1.3.6.1.5.5.7.3.2)} - for those that aren't. So basically IIS binding dialog shows you only relevant certificates (those that are meant to be used as Server Authentication).

It's a little bit tricky to get to that information in code world, here is how I did it:

        List<X509Certificate2> certificates = new List<X509Certificate2>();

        X509Store store1 = new X509Store(StoreName.My, StoreLocation.LocalMachine);
        try
        {
            store1.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

            foreach (var certificate in store1.Certificates)
            {
                foreach (var extension in certificate.Extensions)
                {
                    if (extension.Oid.FriendlyName == "Enhanced Key Usage" && extension is X509EnhancedKeyUsageExtension enhancedKeyUsageExtension)
                    {
                        foreach (var item in enhancedKeyUsageExtension.EnhancedKeyUsages)
                        {
                            if (item.FriendlyName == "Server Authentication")
                            {
                                certificates.Add(certificate);
                            }
                        }
                    }
                }
            }
        }
        finally
        {
            store1.Close();
        }

Upvotes: 1

chalwa
chalwa

Reputation: 82

This is a bit tricky:

First X509Certificate is obsolete use X509Certificate2 instead. Second store is IDisposable so make sure to invoke .Close() or use "using" statement.

My solution:

var store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser);
        try
        {
            var targetCollection = new List<X509Certificate2>();
            
            store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
            var certificates = store.Certificates.Cast<X509Certificate2>();
            targetCollection.AddRange(certificates);
        }
        catch(Exception e)
        {
            //Handle that
        }
        finally
        {
            store.Close();
        }

Of course select proper fields from certificates in tempCollection to yours:

targetCollection.Select(c => new RadListDataItem(c.FriendlyName, c.SerialNumber));

Upvotes: 1

TurboCoder
TurboCoder

Reputation: 71

They're in StoreLocation.LocalMachine. Also, X509Store implements IDisposible, so it should be wrapped in a using statement.

using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
{
     store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
     foreach (var x in store.Certificates)
     {
          radDropDownListIISCert.Items.Add(new RadListDataItem(x.FriendlyName, x.SerialNumber));
     }
}

Upvotes: 4

Related Questions