title: C# Enumerate all hostnames supported by TLS certificates
body: <p>I've been using <a href="https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509store(v=vs.110).aspx" rel="nofollow"><code>System.Security.Cryptography.X509Certificates.X509Store</code></a> for a while now to enumerate all the TLS certificates on the machine (to validate in code whether or not redirecting to SSL will work and warn if the certificate is missing).  I have the following listing function which helps me diagnose issues like the one I'm having right now, but I can't seem to find the data I need:</p>
  
  <pre><code>        System.Security.Cryptography.X509Certificates.X509Store store = new System.Security.Cryptography.X509Certificates.X509Store(System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine);
  
          store.Open(System.Security.Cryptography.X509Certificates.OpenFlags.ReadOnly);
  
          DateTime utcNow = DateTime.UtcNow;
          foreach (System.Security.Cryptography.X509Certificates.X509Certificate2 mCert in store.Certificates)
          {
              writer.WriteStartElement("certificate");
              writer.WriteAttributeString("friendlyName", mCert.FriendlyName);
              writer.WriteAttributeString("subjectName", mCert.SubjectName.Name);
              writer.WriteAttributeString("subject", mCert.Subject);
              writer.WriteAttributeString("simpleName", mCert.GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, false));
              writer.WriteAttributeString("dnsName", mCert.GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType.DnsName, false));
              writer.WriteAttributeString("certhash", mCert.GetCertHashString());
              writer.WriteAttributeString("effectivedate", mCert.GetEffectiveDateString());
              writer.WriteAttributeString("expirationdate", mCert.GetExpirationDateString());
              writer.WriteAttributeString("format", mCert.GetFormat());
              writer.WriteAttributeString("keyalgorithm", mCert.GetKeyAlgorithm());
              writer.WriteAttributeString("publickey", mCert.GetPublicKeyString());
              writer.WriteAttributeString("serialnumber", mCert.SerialNumber);
              writer.WriteAttributeString("hasprivatekey", XmlConvert.ToString(mCert.HasPrivateKey));
              writer.WriteAttributeString("issuer", mCert.Issuer);
              // NOTE: X509Certificate2 as provided by .NET uses local datetimes, so we need to convert them to the sane choice of UTC here 
              writer.WriteAttributeString("notafterutc", XmlConvert.ToString(mCert.NotAfter.ToUniversalTime(), XmlDateTimeSerializationMode.Utc));
              writer.WriteAttributeString("notbeforeutc", XmlConvert.ToString(mCert.NotBefore.ToUniversalTime(), XmlDateTimeSerializationMode.Utc));
              writer.WriteAttributeString("validnow", XmlConvert.ToString(mCert.NotBefore.ToUniversalTime() &lt; utcNow &amp;&amp; utcNow &lt; mCert.NotAfter.ToUniversalTime()));
              writer.WriteAttributeString("timeuntilexpiration", XmlConvert.ToString(mCert.NotAfter.ToUniversalTime() - utcNow));
              writer.WriteAttributeString("thumbprint", mCert.Thumbprint);
              writer.WriteAttributeString("version", mCert.Version.ToString());
              writer.WriteEndElement(); // certificate
          }
          writer.WriteEndElement(); // certificates
          writer.WriteEndResponse();
  </code></pre>
  
  <p>Due to a desire to support a new alternative hostname on the same IP address, we recently switched to using a UCC certificate with multiple hosts.  Unfortunately, the code above doesn't seem to be able to see any of the alternative host names specified in the certificates "Subject Alternative Name" field (the one UCC certificates use to specify multiple hosts), and I'm having trouble finding a property or function that gives me access to this data.</p>
  
  <p>In short, does anyone know how to get the list of supported host names from the "Subject Alternative Name" field of a locally-installed certificate using C#?</p>