Esempio n. 1
0
        public static X509Certificate2Collection FilterValidCerts(
            X509Certificate2Collection certs,
            X509ChainPolicy policy,
            X509ChainStatusFlags problemFlags,
            Action <Exception> notification)
        {
            var validCerts = new X509Certificate2Collection();

            if (certs == null)
            {
                return(null);
            }
            foreach (var cert in certs)
            {
                X509Chain chainBuilder = new X509Chain();
                chainBuilder.ChainPolicy = policy.Clone();

                try
                {
                    // We're using the system class as a helper to merely build the chain
                    // However, we will review each item in the chain ourselves, because we have our own rules...
                    chainBuilder.Build(cert);
                    X509ChainElementCollection chainElements = chainBuilder.ChainElements;

                    // If we don't have a trust chain, then we obviously have a problem...
                    if (chainElements.IsNullOrEmpty())
                    {
                        notification(new Exception(string.Format("Can't find a trust chain: {0} ", cert.Subject)));
                        return(null);
                    }


                    // walk the chain starting at the leaf and see if we hit any issues before the anchor
                    foreach (X509ChainElement chainElement in chainElements)
                    {
                        if (ChainElementHasProblems(chainElement, problemFlags))
                        {
                            //this.NotifyProblem(chainElement);

                            notification(new Exception(string.Format("Chain Element has problem {0}", Summarize(chainElement, problemFlags))));
                            // Whoops... problem with at least one cert in the chain. Stop immediately
                            return(null);
                        }
                    }
                }
                catch (Exception ex)
                {
                    //this.NotifyError(certificate, ex);
                    // just eat it and drop out to return null
                    notification(ex);
                    return(null);
                }
                validCerts.Add(cert);
            }
            return(validCerts);
        }
Esempio n. 2
0
        public static void VerifyCloneBehavior()
        {
            using (X509Certificate2 cert = new X509Certificate2(TestData.SelfSigned1PemBytes))
                using (X509Certificate2 cert2 = new X509Certificate2(TestData.SelfSigned1PemBytes))
                {
                    X509ChainPolicy source = new X509ChainPolicy();
                    source.CertificatePolicy.Add(s_timestampEku);
                    source.ApplicationPolicy.Add(s_emailProtectionEku);
                    source.ExtraStore.Add(cert);
                    source.CustomTrustStore.Add(cert2);
                    source.DisableCertificateDownloads = true;
                    source.VerificationTime            = DateTime.MinValue;
                    source.VerificationTimeIgnored     = false;
                    source.UrlRetrievalTimeout         = TimeSpan.MaxValue;
                    source.VerificationFlags           = X509VerificationFlags.IgnoreCtlNotTimeValid;
                    source.RevocationMode = X509RevocationMode.Offline;
                    source.RevocationFlag = X509RevocationFlag.EntireChain;

                    X509ChainPolicy clone = source.Clone();
                    Assert.Equal(source.VerificationTime, clone.VerificationTime);
                    Assert.Equal(source.VerificationTimeIgnored, clone.VerificationTimeIgnored);
                    Assert.Equal(source.VerificationFlags, clone.VerificationFlags);
                    Assert.Equal(source.RevocationFlag, clone.RevocationFlag);
                    Assert.Equal(source.RevocationMode, clone.RevocationMode);
                    Assert.Equal(source.UrlRetrievalTimeout, clone.UrlRetrievalTimeout);
                    Assert.Equal(source.DisableCertificateDownloads, clone.DisableCertificateDownloads);

                    Assert.NotSame(source.CertificatePolicy, clone.CertificatePolicy);
                    Assert.Equal(source.CertificatePolicy, clone.CertificatePolicy);
                    Assert.Same(source.CertificatePolicy[0], clone.CertificatePolicy[0]);

                    Assert.NotSame(source.ApplicationPolicy, clone.ApplicationPolicy);
                    Assert.Equal(source.ApplicationPolicy, clone.ApplicationPolicy);
                    Assert.Same(source.ApplicationPolicy[0], clone.ApplicationPolicy[0]);

                    Assert.NotSame(source.ExtraStore, clone.ExtraStore);
                    Assert.Equal(source.ExtraStore, clone.ExtraStore);
                    Assert.Same(source.ExtraStore[0], clone.ExtraStore[0]);

                    Assert.NotSame(source.CustomTrustStore, clone.CustomTrustStore);
                    Assert.Equal(source.CustomTrustStore, clone.CustomTrustStore);
                    Assert.Same(source.CustomTrustStore[0], clone.CustomTrustStore[0]);

                    Assert.NotSame(source.ExtraStore[0], clone.CustomTrustStore[0]);
                }
        }
Esempio n. 3
0
        /// <summary>
        /// Validates a certificate by walking the certificate chain for all trust anchor chain, validating the leaf certificate against the chain.
        /// </summary>
        /// <remarks>Currently, all intermediate certificates must be stored in the system.</remarks>
        /// <param name="certificate">The leaf <see cref="X509Certificate2"/> to validate</param>
        /// <param name="anchors">The collection of certificates representing anchors or roots of trust.</param>
        /// <returns><c>true</c> if at least one anchor has a valid chain of certs that verify trust in the leaf certificate,
        /// <c>false</c> if no anchors validate trust in the leaf cert.</returns>
        public bool IsTrustedCertificate(X509Certificate2 certificate, X509Certificate2Collection anchors)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }

            // if there are no anchors we should always fail
            if (CollectionExtensions.IsNullOrEmpty(anchors))
            {
                this.NotifyUntrusted(certificate);
                return(false);
            }

            X509Chain chainBuilder = new X509Chain();

            chainBuilder.ChainPolicy = m_policy.Clone();

            chainBuilder.ChainPolicy.ExtraStore.Add(anchors);
            if (this.HasCertificateResolver)
            {
                this.ResolveIntermediateIssuers(certificate, chainBuilder.ChainPolicy.ExtraStore);
            }

            try
            {
                // We're using the system class as a helper to merely build the chain
                // However, we will review each item in the chain ourselves, because we have our own rules...
                chainBuilder.Build(certificate);
                X509ChainElementCollection chainElements = chainBuilder.ChainElements;

                // If we don't have a trust chain, then we obviously have a problem...
                if (chainElements.IsNullOrEmpty())
                {
                    this.NotifyUntrusted(certificate);
                    return(false);
                }

                bool foundAnchor = false;

                // walk the chain starting at the leaf and see if we hit any issues before the anchor
                foreach (X509ChainElement chainElement in chainElements)
                {
                    bool isAnchor = (anchors.FindByThumbprint(chainElement.Certificate.Thumbprint) != null);
                    if (isAnchor)
                    {
                        // Found a valid anchor!
                        // Because we found an anchor we trust, we can skip trust
                        foundAnchor = true;
                        continue;
                    }

                    if (this.ChainElementHasProblems(chainElement))
                    {
                        this.NotifyProblem(chainElement);

                        // Whoops... problem with at least one cert in the chain. Stop immediately
                        return(false);
                    }
                }

                if (foundAnchor)
                {
                    return(true);
                }

                return(false);
            }
            catch (Exception ex)
            {
                this.NotifyError(certificate, ex);
                // just eat it and drop out to return false
            }

            this.NotifyUntrusted(certificate);
            return(false);
        }