Example #1
0
        protected async Task OneTimeSetUp()
        {
            // start GDS first clean, then restart server
            // to ensure the application cert is not 'fresh'
            _server = await TestUtils.StartGDS(true);

            _server.StopServer();
            await Task.Delay(1000);

            _server = await TestUtils.StartGDS(false);

            _serverCapabilities = new ServerCapabilities();
            _randomSource       = new RandomSource(randomStart);
            _dataGenerator      = new DataGenerator(_randomSource);

            // load clients
            _gdsClient = new GlobalDiscoveryTestClient(true);
            await _gdsClient.LoadClientConfiguration(_server.BasePort);

            _pushClient = new ServerConfigurationPushTestClient(true);
            await _pushClient.LoadClientConfiguration(_server.BasePort);

            // connect once
            await _gdsClient.GDSClient.Connect(_gdsClient.GDSClient.EndpointUrl);

            await _pushClient.PushClient.Connect(_pushClient.PushClient.EndpointUrl);

            ConnectGDSClient(true);
            RegisterPushServerApplication(_pushClient.PushClient.EndpointUrl);

            _selfSignedServerCert = new X509Certificate2(_pushClient.PushClient.Session.ConfiguredEndpoint.Description.ServerCertificate);
            _domainNames          = X509Utils.GetDomainsFromCertficate(_selfSignedServerCert).ToArray();

            await CreateCATestCerts(_pushClient.TempStorePath);
        }
Example #2
0
        /// <summary>
        /// Handles a domain validation error.
        /// </summary>
        /// <param name="caption">The caller's text is used as the caption of the <see cref="MessageBox"/> shown to provide details about the error.</param>
        public static bool HandleDomainCheckError(string caption, ServiceResult serviceResult, X509Certificate2 certificate = null)
        {
            StringBuilder buffer = new StringBuilder();

            buffer.AppendFormat("Certificate could not be validated!\r\n");
            buffer.AppendFormat("Validation error(s): \r\n");
            buffer.AppendFormat("\t{0}\r\n", serviceResult.StatusCode);
            if (certificate != null)
            {
                buffer.AppendFormat("\r\nSubject: {0}\r\n", certificate.Subject);
                buffer.AppendFormat("Issuer: {0}\r\n", X509Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer)
                    ? "Self-signed" : certificate.Issuer);
                buffer.AppendFormat("Valid From: {0}\r\n", certificate.NotBefore);
                buffer.AppendFormat("Valid To: {0}\r\n", certificate.NotAfter);
                buffer.AppendFormat("Thumbprint: {0}\r\n\r\n", certificate.Thumbprint);
                var domains = X509Utils.GetDomainsFromCertficate(certificate);
                if (domains.Count > 0)
                {
                    bool comma = false;
                    buffer.AppendFormat("Domains:");
                    foreach (var domain in domains)
                    {
                        if (comma)
                        {
                            buffer.Append(",");
                        }
                        buffer.AppendFormat(" {0}", domain);
                        comma = true;
                    }
                    buffer.AppendLine();
                }
            }
            buffer.Append("This certificate validation error indicates that the hostname used to connect");
            buffer.Append(" is not listed as a valid hostname in the server certificate.");
            buffer.Append("\r\n\r\nIgnore error and disable the hostname verification?");

            if (MessageBox.Show(buffer.ToString(), caption, MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                return(true);
            }
            return(false);
        }
Example #3
0
        private ServiceResult CreateSigningRequest(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            NodeId certificateGroupId,
            NodeId certificateTypeId,
            string subjectName,
            bool regeneratePrivateKey,
            byte[] nonce,
            ref byte[] certificateRequest)
        {
            HasApplicationSecureAdminAccess(context);

            ServerCertificateGroup certificateGroup = VerifyGroupAndTypeId(certificateGroupId, certificateTypeId);

            if (!String.IsNullOrEmpty(subjectName))
            {
                throw new ArgumentNullException(nameof(subjectName));
            }

            // TODO: implement regeneratePrivateKey
            // TODO: use nonce for generating the private key

            var passwordProvider = m_configuration.SecurityConfiguration.CertificatePasswordProvider;
            X509Certificate2 certWithPrivateKey = certificateGroup.ApplicationCertificate.LoadPrivateKeyEx(passwordProvider).Result;

            Utils.LogCertificate(Utils.TraceMasks.Security, "Create signing request: ", certWithPrivateKey);
            certificateRequest = CertificateFactory.CreateSigningRequest(certWithPrivateKey, X509Utils.GetDomainsFromCertficate(certWithPrivateKey));
            return(ServiceResult.Good);
        }
Example #4
0
        /// <summary>
        /// Checks that the domains in the server addresses match the domains in the certificates.
        /// </summary>
        private static async Task <bool> CheckDomainsInCertificate(
            ApplicationConfiguration configuration,
            X509Certificate2 certificate,
            bool silent)
        {
            Utils.Trace(Utils.TraceMasks.Information, "Checking domains in certificate. {0}", certificate.Subject);

            bool           valid                  = true;
            IList <string> serverDomainNames      = configuration.GetServerDomainNames();
            IList <string> certificateDomainNames = X509Utils.GetDomainsFromCertficate(certificate);

            // get computer name.
            string computerName = Utils.GetHostName();

            // get IP addresses.
            IPAddress[] addresses = null;

            for (int ii = 0; ii < serverDomainNames.Count; ii++)
            {
                if (Utils.FindStringIgnoreCase(certificateDomainNames, serverDomainNames[ii]))
                {
                    continue;
                }

                if (String.Compare(serverDomainNames[ii], "localhost", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    if (Utils.FindStringIgnoreCase(certificateDomainNames, computerName))
                    {
                        continue;
                    }

                    // check for aliases.
                    bool found = false;

                    // get IP addresses only if necessary.
                    if (addresses == null)
                    {
                        addresses = await Utils.GetHostAddressesAsync(computerName);
                    }

                    // check for ip addresses.
                    for (int jj = 0; jj < addresses.Length; jj++)
                    {
                        if (Utils.FindStringIgnoreCase(certificateDomainNames, addresses[jj].ToString()))
                        {
                            found = true;
                            break;
                        }
                    }

                    if (found)
                    {
                        continue;
                    }
                }

                string message = Utils.Format(
                    "The server is configured to use domain '{0}' which does not appear in the certificate. Use certificate?",
                    serverDomainNames[ii]);

                valid = false;

                if (await ApproveMessage(message, silent))
                {
                    valid = true;
                    continue;
                }

                break;
            }

            return(valid);
        }
Example #5
0
        public static void VerifySignedApplicationCert(ApplicationTestData testApp, byte[] rawSignedCert, byte[][] rawIssuerCerts)
        {
            X509Certificate2 signedCert = new X509Certificate2(rawSignedCert);
            X509Certificate2 issuerCert = new X509Certificate2(rawIssuerCerts[0]);

            TestContext.Out.WriteLine($"Signed cert: {signedCert}");
            TestContext.Out.WriteLine($"Issuer cert: {issuerCert}");

            Assert.NotNull(signedCert);
            Assert.False(signedCert.HasPrivateKey);
            Assert.True(X509Utils.CompareDistinguishedName(testApp.Subject, signedCert.Subject));
            Assert.False(X509Utils.CompareDistinguishedName(signedCert.Issuer, signedCert.Subject));
            Assert.True(X509Utils.CompareDistinguishedName(signedCert.Issuer, issuerCert.Subject));
            TestContext.Out.WriteLine($"Signed Subject: {signedCert.Subject}");
            TestContext.Out.WriteLine($"Issuer Subject: {issuerCert.Subject}");

            // test basic constraints
            X509BasicConstraintsExtension constraints = X509Extensions.FindExtension <X509BasicConstraintsExtension>(signedCert);

            Assert.NotNull(constraints);
            TestContext.Out.WriteLine($"Constraints: {constraints.Format(true)}");
            Assert.True(constraints.Critical);
            Assert.False(constraints.CertificateAuthority);
            Assert.False(constraints.HasPathLengthConstraint);

            // key usage
            X509KeyUsageExtension keyUsage = X509Extensions.FindExtension <X509KeyUsageExtension>(signedCert);

            Assert.NotNull(keyUsage);
            TestContext.Out.WriteLine($"KeyUsage: {keyUsage.Format(true)}");
            Assert.True(keyUsage.Critical);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.CrlSign) == 0);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.DataEncipherment) == X509KeyUsageFlags.DataEncipherment);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.DecipherOnly) == 0);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.DigitalSignature) == X509KeyUsageFlags.DigitalSignature);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.EncipherOnly) == 0);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.KeyAgreement) == 0);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.KeyCertSign) == 0);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.KeyEncipherment) == X509KeyUsageFlags.KeyEncipherment);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.NonRepudiation) == X509KeyUsageFlags.NonRepudiation);

            // enhanced key usage
            X509EnhancedKeyUsageExtension enhancedKeyUsage = X509Extensions.FindExtension <X509EnhancedKeyUsageExtension>(signedCert);

            Assert.NotNull(enhancedKeyUsage);
            TestContext.Out.WriteLine($"Enhanced Key Usage: {enhancedKeyUsage.Format(true)}");
            Assert.True(enhancedKeyUsage.Critical);

            // test for authority key
            X509AuthorityKeyIdentifierExtension authority = X509Extensions.FindExtension <X509AuthorityKeyIdentifierExtension>(signedCert);

            Assert.NotNull(authority);
            TestContext.Out.WriteLine($"Authority Key Identifier: {authority.Format(true)}");
            Assert.NotNull(authority.SerialNumber);
            Assert.NotNull(authority.KeyIdentifier);
            Assert.NotNull(authority.Issuer);
            Assert.AreEqual(issuerCert.SubjectName.RawData, authority.Issuer.RawData);
            Assert.AreEqual(issuerCert.SubjectName.RawData, authority.Issuer.RawData);

            // verify authority key in signed cert
            X509SubjectKeyIdentifierExtension subjectKeyId = X509Extensions.FindExtension <X509SubjectKeyIdentifierExtension>(issuerCert);

            TestContext.Out.WriteLine($"Issuer Subject Key Identifier: {subjectKeyId}");
            Assert.AreEqual(subjectKeyId.SubjectKeyIdentifier, authority.KeyIdentifier);
            Assert.AreEqual(issuerCert.SerialNumber, authority.SerialNumber);

            X509SubjectAltNameExtension subjectAlternateName = X509Extensions.FindExtension <X509SubjectAltNameExtension>(signedCert);

            Assert.NotNull(subjectAlternateName);
            TestContext.Out.WriteLine($"Issuer Subject Alternate Name: {subjectAlternateName}");
            Assert.False(subjectAlternateName.Critical);
            var domainNames = X509Utils.GetDomainsFromCertficate(signedCert);

            foreach (var domainName in testApp.DomainNames)
            {
                Assert.True(domainNames.Contains(domainName, StringComparer.OrdinalIgnoreCase));
            }
            Assert.True(subjectAlternateName.Uris.Count == 1);
            var applicationUri = X509Utils.GetApplicationUriFromCertificate(signedCert);

            Assert.True(testApp.ApplicationRecord.ApplicationUri == applicationUri);
        }
        public static void VerifyApplicationCert(ApplicationTestData testApp, X509Certificate2 cert, X509Certificate2 issuerCert = null)
        {
            bool signedCert = issuerCert != null;

            if (issuerCert == null)
            {
                issuerCert = cert;
            }
            TestContext.Out.WriteLine($"{nameof(VerifyApplicationCert)}:");
            Assert.NotNull(cert);
            TestContext.Out.WriteLine(cert);
            Assert.False(cert.HasPrivateKey);
            Assert.True(X509Utils.CompareDistinguishedName(testApp.Subject, cert.Subject));
            Assert.True(X509Utils.CompareDistinguishedName(issuerCert.Subject, cert.Issuer));

            // test basic constraints
            X509BasicConstraintsExtension constraints = X509Extensions.FindExtension <X509BasicConstraintsExtension>(cert);

            Assert.NotNull(constraints);
            TestContext.Out.WriteLine(constraints.Format(true));
            Assert.True(constraints.Critical);
            if (signedCert)
            {
                Assert.False(constraints.CertificateAuthority);
                Assert.False(constraints.HasPathLengthConstraint);
            }
            else
            {
                Assert.True(constraints.CertificateAuthority);
                Assert.True(constraints.HasPathLengthConstraint);
                Assert.AreEqual(0, constraints.PathLengthConstraint);
            }

            // key usage
            X509KeyUsageExtension keyUsage = X509Extensions.FindExtension <X509KeyUsageExtension>(cert);

            Assert.NotNull(keyUsage);
            TestContext.Out.WriteLine(keyUsage.Format(true));
            Assert.True(keyUsage.Critical);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.CrlSign) == 0);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.DataEncipherment) == X509KeyUsageFlags.DataEncipherment);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.DecipherOnly) == 0);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.DigitalSignature) == X509KeyUsageFlags.DigitalSignature);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.EncipherOnly) == 0);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.KeyAgreement) == 0);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.KeyCertSign) == (signedCert ? 0 : X509KeyUsageFlags.KeyCertSign));
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.KeyEncipherment) == X509KeyUsageFlags.KeyEncipherment);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.NonRepudiation) == X509KeyUsageFlags.NonRepudiation);

            // enhanced key usage
            X509EnhancedKeyUsageExtension enhancedKeyUsage = X509Extensions.FindExtension <X509EnhancedKeyUsageExtension>(cert);

            Assert.NotNull(enhancedKeyUsage);
            TestContext.Out.WriteLine(enhancedKeyUsage.Format(true));
            Assert.True(enhancedKeyUsage.Critical);

            // test for authority key
            X509AuthorityKeyIdentifierExtension authority = X509Extensions.FindExtension <X509AuthorityKeyIdentifierExtension>(cert);

            Assert.NotNull(authority);
            TestContext.Out.WriteLine(authority.Format(true));
            Assert.NotNull(authority.SerialNumber);
            Assert.NotNull(authority.KeyIdentifier);
            Assert.NotNull(authority.Issuer);
            if (issuerCert == null)
            {
                Assert.AreEqual(cert.SubjectName.RawData, authority.Issuer.RawData);
                Assert.True(X509Utils.CompareDistinguishedName(cert.SubjectName.Name, authority.Issuer.Name), $"{cert.SubjectName.Name} != {authority.Issuer.Name}");
            }
            else
            {
                Assert.AreEqual(issuerCert.SubjectName.RawData, authority.Issuer.RawData);
                Assert.True(X509Utils.CompareDistinguishedName(issuerCert.SubjectName.Name, authority.Issuer.Name), $"{cert.SubjectName.Name} != {authority.Issuer.Name}");
            }

            // verify authority key in signed cert
            X509SubjectKeyIdentifierExtension subjectKeyId = X509Extensions.FindExtension <X509SubjectKeyIdentifierExtension>(cert);

            TestContext.Out.WriteLine(subjectKeyId.Format(true));
            if (signedCert)
            {
                var caCertSubjectKeyId = X509Extensions.FindExtension <X509SubjectKeyIdentifierExtension>(issuerCert);
                Assert.NotNull(caCertSubjectKeyId);
                Assert.AreEqual(caCertSubjectKeyId.SubjectKeyIdentifier, authority.KeyIdentifier);
            }
            else
            {
                Assert.AreEqual(subjectKeyId.SubjectKeyIdentifier, authority.KeyIdentifier);
            }
            Assert.AreEqual(issuerCert.GetSerialNumber(), authority.GetSerialNumber());
            Assert.AreEqual(issuerCert.SerialNumber, authority.SerialNumber);

            X509SubjectAltNameExtension subjectAlternateName = X509Extensions.FindExtension <X509SubjectAltNameExtension>(cert);

            Assert.NotNull(subjectAlternateName);
            TestContext.Out.WriteLine(subjectAlternateName.Format(true));
            Assert.False(subjectAlternateName.Critical);
            var domainNames = X509Utils.GetDomainsFromCertficate(cert);

            foreach (var domainName in testApp.DomainNames)
            {
                Assert.True(domainNames.Contains(domainName, StringComparer.OrdinalIgnoreCase));
            }
            Assert.True(subjectAlternateName.Uris.Count == 1);
            var applicationUri = X509Utils.GetApplicationUriFromCertificate(cert);

            TestContext.Out.WriteLine("ApplicationUri: ");
            TestContext.Out.WriteLine(applicationUri);
            Assert.AreEqual(testApp.ApplicationUri, applicationUri);
        }
        /// <summary>
        /// Displays the dialog.
        /// </summary>
        public async Task<bool> ShowDialog(CertificateIdentifier certificate)
        {
            m_certificate = certificate;

            CertificateStoreCTRL.StoreType = null;
            CertificateStoreCTRL.StorePath = null;
            CertificateStoreCTRL.ReadOnly = true;
            ApplicationNameTB.Text = null;
            ApplicationUriTB.Text = null;
            OrganizationTB.Text = null;
            DomainsTB.Text = System.Net.Dns.GetHostName();
            SubjectNameTB.Text = null;
            IssuerNameTB.Text = null;
            ValidFromTB.Text = null;
            ValidToTB.Text = null;
            ThumbprintTB.Text = null;

            if (certificate != null)
            {
                CertificateStoreCTRL.StoreType = certificate.StoreType;
                CertificateStoreCTRL.StorePath = certificate.StorePath;
                SubjectNameTB.Text = certificate.SubjectName;
                ThumbprintTB.Text = certificate.Thumbprint;

                X509Certificate2 data = await certificate.Find();

                if (data != null)
                {
                    // fill in subject name.
                    StringBuilder buffer = new StringBuilder();

                    foreach (string element in X509Utils.ParseDistinguishedName(data.Subject))
                    {
                        if (element.StartsWith("CN="))
                        {
                            ApplicationNameTB.Text = element.Substring(3);
                        }

                        if (element.StartsWith("O="))
                        {

                            OrganizationTB.Text = element.Substring(2);
                        }

                        if (buffer.Length > 0)
                        {
                            buffer.Append('/');
                        }

                        buffer.Append(element);
                    }

                    if (buffer.Length > 0)
                    {
                        SubjectNameTB.Text = buffer.ToString();
                    }

                    // fill in issuer name.
                    buffer = new StringBuilder();

                    foreach (string element in X509Utils.ParseDistinguishedName(data.Issuer))
                    {
                        if (buffer.Length > 0)
                        {
                            buffer.Append('/');
                        }

                        buffer.Append(element);
                    }

                    if (buffer.Length > 0)
                    {
                        IssuerNameTB.Text = buffer.ToString();
                    }

                    // fill in application uri.
                    string applicationUri = X509Utils.GetApplicationUriFromCertificate(data);

                    if (!String.IsNullOrEmpty(applicationUri))
                    {
                        ApplicationUriTB.Text = applicationUri;
                    }

                    // fill in domains.
                    buffer = new StringBuilder();

                    foreach (string domain in X509Utils.GetDomainsFromCertficate(data))
                    {
                        if (buffer.Length > 0)
                        {
                            buffer.Append(", ");
                        }

                        buffer.Append(domain);
                    }

                    if (buffer.Length > 0)
                    {
                        DomainsTB.Text = buffer.ToString();
                    }

                    ValidFromTB.Text = data.NotBefore.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
                    ValidToTB.Text = data.NotAfter.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
                    ThumbprintTB.Text = data.Thumbprint;
                }
            }

            if (ShowDialog() != DialogResult.OK)
            {
                return false;
            }

            return true;
        }
        /// <summary>
        /// Checks if the certicate meets the filter criteria.
        /// </summary>
        /// <param name="certificate">The certificate.</param>
        /// <returns>True if it meets the criteria.</returns>
        public bool Match(X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                return(false);
            }

            try
            {
                if (!String.IsNullOrEmpty(m_subjectName))
                {
                    if (!Utils.Match(certificate.Subject, "CN*" + m_subjectName + ",*", false))
                    {
                        return(false);
                    }
                }

                if (!String.IsNullOrEmpty(m_issuerName))
                {
                    if (!Utils.Match(certificate.Issuer, "CN*" + m_issuerName + ",*", false))
                    {
                        return(false);
                    }
                }

                if (!String.IsNullOrEmpty(m_domain))
                {
                    IList <string> domains = X509Utils.GetDomainsFromCertficate(certificate);

                    bool found = false;

                    for (int ii = 0; ii < domains.Count; ii++)
                    {
                        if (Utils.Match(domains[ii], m_domain, false))
                        {
                            found = true;
                            break;
                        }
                    }

                    if (!found)
                    {
                        return(false);
                    }
                }

                // check for private key.
                if (m_privateKey)
                {
                    if (!certificate.HasPrivateKey)
                    {
                        return(false);
                    }
                }

                if (m_certificateTypes != null)
                {
                    // determine if a CA certificate.
                    bool isCA = X509Utils.IsCertificateAuthority(certificate);

                    // determine if self-signed.
                    bool isSelfSigned = X509Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer);

                    // match if one or more of the criteria match.
                    bool found = false;

                    for (int ii = 0; ii < m_certificateTypes.Length; ii++)
                    {
                        switch (m_certificateTypes[ii])
                        {
                        case CertificateListFilterType.Application:
                        {
                            if (!isCA)
                            {
                                found = true;
                            }

                            break;
                        }

                        case CertificateListFilterType.CA:
                        {
                            if (isCA)
                            {
                                found = true;
                            }

                            break;
                        }

                        case CertificateListFilterType.SelfSigned:
                        {
                            if (isSelfSigned)
                            {
                                found = true;
                            }

                            break;
                        }

                        case CertificateListFilterType.Issued:
                        {
                            if (!isSelfSigned)
                            {
                                found = true;
                            }

                            break;
                        }
                        }
                    }

                    if (!found)
                    {
                        return(false);
                    }
                }

                return(true);
            }
            catch (Exception)
            {
                return(false);
            }
        }
Example #9
0
        /// <summary>
        /// Updates an item in the view.
        /// </summary>
        protected override void UpdateItem(ListViewItem listItem, object item)
        {
            X509Certificate2 certificate = item as X509Certificate2;

            if (certificate == null)
            {
                base.UpdateItem(listItem, item);
                return;
            }

            listItem.SubItems[0].Text = null;
            listItem.SubItems[1].Text = null;
            listItem.SubItems[2].Text = null;
            listItem.SubItems[3].Text = null;
            listItem.SubItems[4].Text = null;
            listItem.SubItems[5].Text = null;

            if (certificate != null)
            {
                List <string> fields = X509Utils.ParseDistinguishedName(certificate.Subject);

                for (int ii = 0; ii < fields.Count; ii++)
                {
                    if (fields[ii].StartsWith("CN="))
                    {
                        listItem.SubItems[0].Text = fields[ii].Substring(3);
                    }

                    if (fields[ii].StartsWith("DC="))
                    {
                        listItem.SubItems[1].Text = fields[ii].Substring(3);
                    }
                }

                if (String.IsNullOrEmpty(listItem.SubItems[0].Text))
                {
                    listItem.SubItems[0].Text = String.Format("{0}", certificate.Subject);
                }

                // determine certificate type.
                foreach (X509Extension extension in certificate.Extensions)
                {
                    X509BasicConstraintsExtension basicContraints = extension as X509BasicConstraintsExtension;

                    if (basicContraints != null)
                    {
                        if (basicContraints.CertificateAuthority)
                        {
                            listItem.SubItems[1].Text = "CA";
                        }
                        else
                        {
                            listItem.SubItems[1].Text = "End-Entity";
                        }

                        break;
                    }
                }

                // check if a private key is available.
                if (certificate.HasPrivateKey)
                {
                    listItem.SubItems[2].Text = "Yes";
                }
                else
                {
                    listItem.SubItems[2].Text = "No";
                }

                // look up domains.
                IList <string> domains = X509Utils.GetDomainsFromCertficate(certificate);

                StringBuilder buffer = new StringBuilder();

                for (int ii = 0; ii < domains.Count; ii++)
                {
                    if (buffer.Length > 0)
                    {
                        buffer.Append(";");
                    }

                    buffer.Append(domains[ii]);
                }

                listItem.SubItems[3].Text = buffer.ToString();
                listItem.SubItems[4].Text = X509Utils.GetApplicationUriFromCertificate(certificate);
                listItem.SubItems[5].Text = String.Format("{0:yyyy-MM-dd}", certificate.NotAfter);
            }

            listItem.ImageKey = GuiUtils.Icons.Certificate;
            listItem.Tag      = item;
        }
        public List <string> GetDomainNames(X509Certificate2 certificate)
        {
            List <string> domainNames = new List <string>();

            if (!String.IsNullOrEmpty(Domains))
            {
                var domains = Domains.Split(',');

                List <string> trimmedDomains = new List <string>();

                foreach (var domain in domains)
                {
                    var d = domain.Trim();

                    if (d.Length > 0)
                    {
                        trimmedDomains.Add(d);
                    }
                }

                if (trimmedDomains.Count > 0)
                {
                    return(trimmedDomains);
                }
            }

            if (DiscoveryUrl != null)
            {
                foreach (var discoveryUrl in DiscoveryUrl)
                {
                    if (Uri.IsWellFormedUriString(discoveryUrl, UriKind.Absolute))
                    {
                        string name = new Uri(discoveryUrl).DnsSafeHost;

                        if (name == "localhost")
                        {
                            name = Utils.GetHostName();
                        }

                        bool found = false;

                        //domainNames.Any(n => String.Compare(n, name, StringComparison.OrdinalIgnoreCase) == 0);
                        foreach (var domainName in domainNames)
                        {
                            if (String.Compare(domainName, name, StringComparison.OrdinalIgnoreCase) == 0)
                            {
                                found = true;
                                break;
                            }
                        }

                        if (!found)
                        {
                            domainNames.Add(name);
                        }
                    }
                }
            }

            if (domainNames != null && domainNames.Count > 0)
            {
                return(domainNames);
            }

            if (certificate != null)
            {
                var names = X509Utils.GetDomainsFromCertficate(certificate);

                if (names != null && names.Count > 0)
                {
                    domainNames.AddRange(names);
                    return(domainNames);
                }

                var fields = X509Utils.ParseDistinguishedName(certificate.Subject);

                string name = null;

                foreach (var field in fields)
                {
                    if (field.StartsWith("DC=", StringComparison.Ordinal))
                    {
                        if (name != null)
                        {
                            name += ".";
                        }

                        name += field.Substring(3);
                    }
                }

                if (names != null)
                {
                    domainNames.AddRange(names);
                    return(domainNames);
                }
            }

            domainNames.Add(Utils.GetHostName());
            return(domainNames);
        }