public static CertificateErrors GetCertificateErrors(X509ChainElement chainElement)
        {
            //If the length is not zero and the items aren't "OK", return critical.
            if (chainElement.ChainElementStatus.Length != 0 && !chainElement.ChainElementStatus.All(s => s.Status == X509ChainStatusFlags.NoError))
            {
                return(CertificateErrors.Critical);
            }
            //Recheck with revocation
            var chain = new X509Chain();

            chain.ChainPolicy.RevocationMode    = X509RevocationMode.Online;
            chain.ChainPolicy.RevocationFlag    = X509RevocationFlag.EndCertificateOnly;
            chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags & ~X509VerificationFlags.IgnoreEndRevocationUnknown;
            var builtChain = chain.Build(chainElement.Certificate);

            if (chain.ChainStatus.Any(s => s.Status == X509ChainStatusFlags.RevocationStatusUnknown))
            {
                return(CertificateErrors.UnknownRevocation);
            }
            if (!builtChain)
            {
                return(CertificateErrors.Critical);
            }
            return(CertificateErrors.None);
        }
예제 #2
0
        internal static bool VerifyWithExtraRoots(
            this X509Chain chain,
            X509Certificate certificate,
            X509Certificate2Collection extraRoots)
        {
            chain.ChainPolicy.ExtraStore.AddRange(extraRoots);
            if (chain.Build(new X509Certificate2(certificate)))
            {
                return(true);
            }
            else
            {
                // .NET returns UntrustedRoot status flag if the certificate is not in
                // the SYSTEM trust store. Check if it's the only problem with the chain.
                bool onlySystemUntrusted =
                    chain.ChainStatus.Length == 1 &&
                    chain.ChainStatus[0].Status == X509ChainStatusFlags.UntrustedRoot;

                // Sanity check that indeed that is the only problem with the root
                // certificate.
                X509ChainElement rootCert = chain.ChainElements[chain.ChainElements.Count - 1];
                bool             rootOnlySystemUntrusted =
                    rootCert.ChainElementStatus.Length == 1 &&
                    rootCert.ChainElementStatus[0].Status
                    == X509ChainStatusFlags.UntrustedRoot;

                // Double check it's indeed one of the extra roots we've been given.
                bool rootIsUserTrusted = extraRoots.Contains(rootCert.Certificate);

                return
                    (onlySystemUntrusted && rootOnlySystemUntrusted && rootIsUserTrusted);
            }
        }
예제 #3
0
        public static void PrintChain(X509Chain Chain)
        {
            for (int i = Chain.ChainElements.Count - 1; !(i < 0); i--)
            {
                X509ChainElement element = Chain.ChainElements[i];
                string           name    = DistinguishedNameParser.Parse(element.Certificate.SubjectName)["CN"];

                Console.Write(name);
                X509KeyUsageFlags flags = _GetUsage(element.Certificate);
                if (flags == X509KeyUsageFlags.None)
                {
                    Console.Write(" [NoLimit]");
                }
                else if (flags.HasFlag(X509KeyUsageFlags.KeyCertSign) && flags.HasFlag(X509KeyUsageFlags.CrlSign))
                {
                    Console.Write(" [CrtSign]");
                }
                if (element.Certificate.HasPrivateKey)
                {
                    Console.Write(" [PriKey]");
                }
                Console.WriteLine();

                foreach (X509ChainStatus status in element.ChainElementStatus)
                {
                    Console.WriteLine("`- " + status.Status);
                    Console.WriteLine("   " + status.StatusInformation);
                }
                if (i > 0)
                {
                    Console.WriteLine("  |||");
                }
            }
        }
예제 #4
0
        private void WrapUp()
        {
            X509ChainElement   element     = elements[0];
            BCX509Certificate2 certificate = element.BCCertificate;

            // 6.1.5.a - TODO if certificate n (our 0) wasn't self issued and explicit_policy != 0
            if (IsSelfIssued(certificate))
            {
                // TODO... decrement explicit_policy by 1
            }

            // 6.1.5.b - TODO

            // 6.1.5.c,d,e - not required by the X509Chain implementation

            // 6.1.5.f - recognize and process other critical extension present in the certificate
            ProcessCertificateExtensions(element);

            // 6.1.5.g - TODO

            // uncompressed the flags into several elements
            for (int i = elements.Count - 1; i >= 0; i--)
            {
                elements[i].UncompressFlags();
            }
        }
예제 #5
0
        private void ProcessCertificateExtensions(X509ChainElement element)
        {
            var exts = element.BCCertificate.CertificateStructure.TbsCertificate.Extensions;

            foreach (var extOid in exts.GetExtensionOids())
            {
                var ext = exts.GetExtension(extOid);
                if (ext.IsCritical)
                {
                    switch (extOid.Id)
                    {
                    case "2.5.29.15":                             // X509KeyUsageExtension
                    case "2.5.29.19":                             // X509BasicConstraintsExtension
                        // we processed this extension
                        break;

                    default:
                        // note: Under Windows XP MS implementation seems to ignore
                        // certificate with unknown critical extensions.
                        element.StatusFlags |= X509ChainStatusFlags.InvalidExtension;
                        break;
                    }
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Remotes the certificate validation callback.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="certificate">The certificate.</param>
        /// <param name="chain">The chain.</param>
        /// <param name="sslPolicyErrors">The SSL policy errors.</param>
        /// <returns></returns>
        public static bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain,
                                                               SslPolicyErrors sslPolicyErrors)
        {
            if (SslPolicyErrors.None == sslPolicyErrors)
            {
                return(true);
            }

            if (SslPolicyErrors.None == sslPolicyErrors ||
                SslPolicyErrors.RemoteCertificateChainErrors == sslPolicyErrors ||
                (SslPolicyErrors.RemoteCertificateChainErrors | SslPolicyErrors.RemoteCertificateNameMismatch) ==
                sslPolicyErrors)
            {
                if (null != chain && chain.ChainStatus.Length == 1 &&
                    chain.ChainStatus[0].Status == X509ChainStatusFlags.UntrustedRoot)
                {
                    X509ChainElement rootElement = chain.ChainElements[chain.ChainElements.Count - 1];

                    if (rootElement.Certificate.Equals(_rootAuthority1) || rootElement.Certificate.Equals(_rootAuthority2))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #7
0
        // This isn't how RFC3280 (section 6.3) deals with CRL, but then we don't (yet) support DP, deltas...
        private X509ChainStatusFlags CheckRevocation(BCX509Certificate2 certificate, int ca, bool online)
        {
            X509ChainStatusFlags result  = X509ChainStatusFlags.RevocationStatusUnknown;
            X509ChainElement     element = elements[ca];
            BCX509Certificate2   ca_cert = element.BCCertificate;

            // find the CRL from the "right" CA
            while (IsSelfIssued(ca_cert) && (ca < elements.Count - 1))
            {
                // try with this self-issued
                result = CheckRevocation(certificate, ca_cert, online);
                if (result != X509ChainStatusFlags.RevocationStatusUnknown)
                {
                    break;
                }
                ca++;
                element = elements[ca];
                ca_cert = element.BCCertificate;
            }
            if (result == X509ChainStatusFlags.RevocationStatusUnknown)
            {
                result = CheckRevocation(certificate, ca_cert, online);
            }
            return(result);
        }
예제 #8
0
 internal void OnCertificateProblem(X509ChainElement chainElement)
 {
     if (chainElement != null)
     {
         Logger.Error("Chain Element has problem {0}", this.Summarize(chainElement));
     }
 }
예제 #9
0
        private CertificateModel AssignCertificate(X509ChainElement chainElement, bool reportOnly, PublicPinnedKeys pinnedKey, X509Chain chain, int index)
        {
            var certificate   = chainElement.Certificate;
            var algorithmBits = BitStrengthCalculator.CalculateStrength(certificate);
            var dn            = DistinguishedNameParser.Parse(certificate.Subject);

            return(new CertificateModel
            {
                CommonName = dn.ContainsKey("cn") ? dn["cn"].FirstOrDefault() ?? certificate.Thumbprint : certificate.Thumbprint,
                Thumbprint = certificate.Thumbprint,
                DistinguishedName = dn,
                SubjectAlternativeName = certificate.Extensions[KnownOids.X509Extensions.SubjectAltNameExtension]?.Format(false) ?? "None",
                PublicKey = new PublicKeyModel
                {
                    Algorithm = algorithmBits.AlgorithmName,
                    KeySizeBits = algorithmBits.BitSize,
                    PublicKey = certificate.PublicKey.EncodedKeyValue.RawData
                },
                BeginDate = certificate.NotBefore,
                EndDate = certificate.NotAfter,
                SerialNumber = certificate.SerialNumber ?? "None",
                SignatureAlgorithm = new SignatureAlgorithmModel
                {
                    SignatureAlgorithm = certificate.SignatureAlgorithm,
                    IsTrustedRoot = _rootStore.Certificates.Contains(certificate) || _userStore.Certificates.Contains(certificate)
                },
                CertificateType = index == 0 ? GetCertificateType(certificate, chain) : CertificateType.None,
                Errors = new AsyncProperty <CertificateErrors>(Task.Factory.StartNew(() => CertificateErrorsCalculator.GetCertificateErrors(chainElement))),
                SpkiHashes = new AsyncProperty <SpkiHashesModel>(Task.Factory.StartNew(() => CalculateHashes(chainElement.Certificate, reportOnly, pinnedKey))),
                InstallCommand = new RelayCommand(parameter => CertificateUI.ShowImportCertificate(chainElement.Certificate, FiddlerApplication.UI)),
                ViewCommand = new RelayCommand(parameter => CertificateUI.ShowCertificate(chainElement.Certificate, FiddlerApplication.UI))
            });
        }
예제 #10
0
        public static void TestLeafCertificateWithUnknownCriticalExtension()
        {
            using (RSA key = RSA.Create())
            {
                CertificateRequest certReq = new CertificateRequest(
                    new X500DistinguishedName("CN=Cert"),
                    key,
                    HashAlgorithmName.SHA256,
                    RSASignaturePadding.Pkcs1);

                const string PrecertificatePoisonExtensionOid = "1.3.6.1.4.1.11129.2.4.3";
                certReq.CertificateExtensions.Add(new X509Extension(
                                                      new AsnEncodedData(
                                                          new Oid(PrecertificatePoisonExtensionOid),
                                                          new byte[] { 5, 0 }),
                                                      critical: true));

                DateTimeOffset notBefore = DateTimeOffset.UtcNow.AddDays(-1);
                DateTimeOffset notAfter  = notBefore.AddDays(30);

                using (X509Certificate2 cert = certReq.CreateSelfSigned(notBefore, notAfter))
                    using (ChainHolder holder = new ChainHolder())
                    {
                        X509Chain chain = holder.Chain;
                        chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
                        Assert.False(chain.Build(cert));

                        X509ChainElement           certElement  = chain.ChainElements.OfType <X509ChainElement>().Single();
                        const X509ChainStatusFlags ExpectedFlag = X509ChainStatusFlags.HasNotSupportedCriticalExtension;
                        X509ChainStatusFlags       actualFlags  = certElement.AllStatusFlags();
                        Assert.True((actualFlags & ExpectedFlag) == ExpectedFlag, $"Has expected flag {ExpectedFlag} but was {actualFlags}");
                    }
            }
        }
        private static string RunChain(
            X509Chain chain,
            X509Certificate2 cert,
            string msg)
        {
            bool success = chain.Build(cert);

            FormattableString errMsg = null;

            if (!success)
            {
                for (int i = 0; i < chain.ChainElements.Count; i++)
                {
                    X509ChainElement element = chain.ChainElements[i];

                    if (element.ChainElementStatus.Length != 0)
                    {
                        X509ChainStatusFlags flags =
                            element.ChainElementStatus.Select(ces => ces.Status).Aggregate((a, b) => a | b);

                        errMsg = $"{msg}: chain error at depth {i}: {flags}";
                        break;
                    }
                }
            }

            return(errMsg?.ToString(formatProvider: CultureInfo.CurrentCulture));
        }
            public void GyldigKjedeMedUkjentRotnodeOgUgyldigOnlineOppslag()
            {
                //Arrange
                var        gyldigSertifikat          = new X509Certificate2(ResourceUtility.ReadAllBytes(true, "test", "testmottakersertifikatFraOppslagstjenesten.pem"));
                const bool ignoreStoreMySertifikater = true;
                var        chain = new X509Chain(ignoreStoreMySertifikater)
                {
                    ChainPolicy = ChainPolicyWithOnlineCheckOgUkjentRotnode
                };

                //Act
                chain.Build(gyldigSertifikat);
                var chainElements = new X509ChainElement[chain.ChainElements.Count];

                chain.ChainElements.CopyTo(chainElements, 0);

                //Assert
                var elementerMedRevokeringsstatusUkjent = chainElements.Select(chainElement => new
                {
                    Status = chainElement.ChainElementStatus
                             .Where(elementStatus => elementStatus.Status == X509ChainStatusFlags.RevocationStatusUnknown)
                }).Where(node => node.Status.Any());

                Assert.AreEqual(2, elementerMedRevokeringsstatusUkjent.Count());

                var rotNode = chainElements[0];

                Assert.AreEqual(0, rotNode.ChainElementStatus.Count(elementStatus => elementStatus.Status == X509ChainStatusFlags.UntrustedRoot));
            }
예제 #13
0
        private void LogInvalidCertificate(X509Certificate certificate, X509Chain chain)
        {
            string policyInfo = string.Empty;

            if (chain.ChainPolicy != null)
            {
                policyInfo = "RevocationMode: " + chain.ChainPolicy.RevocationMode + ", RevocationFlag: " + chain.ChainPolicy.RevocationFlag + ", VerificationFlags: " + chain.ChainPolicy.VerificationFlags;
            }

            string chainErrors = string.Empty;

            if (chain.ChainStatus != null)
            {
                foreach (X509ChainStatus status in chain.ChainStatus)
                {
                    if (!string.IsNullOrEmpty(chainErrors))
                    {
                        chainErrors += "\r\n";
                    }
                    chainErrors += status.Status.ToString() + ": " + status.StatusInformation;
                }
            }

            string chainElements = string.Empty;

            for (var i = 0; i < chain.ChainElements.Count; i++)
            {
                X509ChainElement cel = chain.ChainElements[i];
                if (cel.ChainElementStatus != null && cel.ChainElementStatus.Length > 0)
                {
                    if (!string.IsNullOrEmpty(chainElements))
                    {
                        chainElements += "\r\n";
                    }

                    string cName = string.Empty;
                    if (cel.Certificate != null)
                    {
                        cName = cel.Certificate.Subject;
                    }

                    chainElements += cName + ":";

                    foreach (X509ChainStatus status in cel.ChainElementStatus)
                    {
                        if (status.Status == X509ChainStatusFlags.NotTimeValid && cel.Certificate != null)
                        {
                            chainElements += "\r\n" + status.Status.ToString() + ": " + cel.Certificate.NotBefore.ToString("yyyy-MM-dd HH:mm:ss") + " - " + cel.Certificate.NotAfter.ToString("yyyy-MM-dd HH:mm:ss") + ": " + status.StatusInformation;
                        }
                        else
                        {
                            chainElements += "\r\n" + status.Status.ToString() + ": " + status.StatusInformation;
                        }
                    }
                }
            }

            _logger.LogWarning(string.Format("Failed to validate certificate '{0}'. policy: {1}\r\nchainErrors:\r\n{2}\r\nchainElements:\r\n{3}", certificate.Subject, policyInfo, chainErrors, chainElements));
        }
예제 #14
0
        public X509Certificate2 Load()
        {
            if (!File.Exists(Filename))
            {
                Logger.LogError("Cannot load certificate because the file does not exist: {0}", Filename);
                return(null);
            }

            Logger.Log("Loading...");
            X509Certificate2 certificate = null;

            try
            {
                certificate = new X509Certificate2(Filename, Password);
            }
            catch (Exception e)
            {
                Logger.LogError(e, "Failed to load certificate: {0}");
                return(null);
            }

            Logger.Log("Verifying...");
            X509Chain chain = new X509Chain();

            chain.ChainPolicy.RevocationFlag      = X509RevocationFlag.EndCertificateOnly;
            chain.ChainPolicy.RevocationMode      = X509RevocationMode.NoCheck;
            chain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromSeconds(5);
            chain.ChainPolicy.VerificationFlags   = X509VerificationFlags.AllowUnknownCertificateAuthority | X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown;

            bool happy = chain.Build(certificate);
            bool valid = true;

            //Get elements
            X509ChainElementCollection elements = chain.ChainElements;

            Logger.Log($"Chain built with {elements.Count} elements, happy={happy}");

            //Make sure each element is okay
            for (int i = 0; i < elements.Count; i++)
            {
                X509ChainElement element = elements[i];
                Logger.Log($" > Element {i}: {element.Certificate.GetNameInfo(X509NameType.SimpleName, false)}");
                foreach (X509ChainStatus status in element.ChainElementStatus)
                {
                    Logger.LogError($" >>> {status.Status}: {status.StatusInformation}");
                    valid = false;
                }
            }

            //Final check
            if (!happy && !valid)
            {
                Logger.LogError("Failed to load certificate! Happy: {0}, Valid: {1}", happy, valid);
                return(null);
            }

            //return the certificate
            return(certificate);
        }
        /// <summary>
        /// The Dropbox certificate validation callback.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="certificate">The certificate.</param>
        /// <param name="chain">The chain.</param>
        /// <param name="sslpolicyerrors">The sslpolicyerrors.</param>
        /// <returns></returns>
        private static bool DropboxCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain,
                                                                 SslPolicyErrors sslpolicyerrors)
        {
            X509ChainElement root      = chain.ChainElements[chain.ChainElements.Count - 1];
            string           publicKey = root.Certificate.GetPublicKeyString();

            return(DropboxCertHelper.IsKnownRootCertPublicKey(publicKey));
        }
        public static bool RemoteCertificateValidationCallback(
            object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            if (SslPolicyErrors.None == sslPolicyErrors)
            {
                return(true);
            }

            if (DisableValidation)
            {
                return(true);
            }

            // Сертификат не установлен в корневое хранилище
            if (SslPolicyErrors.RemoteCertificateChainErrors == sslPolicyErrors)
            {
                if (1 == chain.ChainStatus.Length &&
                    (chain.ChainStatus[0].Status.HasFlag(X509ChainStatusFlags.UntrustedRoot) || chain.ChainStatus[0]
                     .Status.HasFlag(X509ChainStatusFlags.PartialChain)))
                {
                    X509ChainElement rootElement = chain.ChainElements[chain.ChainElements.Count - 1];

                    lock (Anchor)
                    {
                        foreach (X509Certificate2 trustedCertificate in TrustedCertificateList)
                        {
                            if (rootElement.Certificate.Equals(trustedCertificate))
                            {
                                return(true);
                            }

                            Logger.DebugFormat("{0} != {1}", rootElement.Certificate.Thumbprint,
                                               trustedCertificate.Thumbprint);
                        }
                    }
                }
                else
                {
                    Logger.Debug("chain.ChainStatus.Length == " + chain.ChainStatus.Length);

                    int index = 0;

                    foreach (var chainStatus in chain.ChainStatus)
                    {
                        Logger.DebugFormat("chainStatus[{0}] == {1}", index, chainStatus.Status);
                        index++;
                    }
                }
            }
            else
            {
                Logger.Debug("sslPolicyErrors.HasFlag(SslPolicyErrors.RemoteCertificateChainErrors) == " + sslPolicyErrors.HasFlag(SslPolicyErrors.RemoteCertificateChainErrors));
                Logger.Debug("sslPolicyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch) == " + sslPolicyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch));
                Logger.Debug("sslPolicyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNotAvailable) == " + sslPolicyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNotAvailable));
            }

            return(false);
        }
예제 #17
0
 internal ChainElement(X509ChainElement source)
     : this()
 {
     this.Certificate = source.Certificate;
     this.ChainElementStatus.AddRange(source.ChainElementStatus.Where(x =>
                                                                      x.Status != X509ChainStatusFlags.OfflineRevocation &&
                                                                      x.Status != X509ChainStatusFlags.RevocationStatusUnknown &&
                                                                      x.Status != X509ChainStatusFlags.Revoked));
 }
예제 #18
0
        public static void VerifyWithRevocation()
        {
            using (var cert = new X509Certificate2(Path.Combine("TestData", "MS.cer")))
                using (var onlineChainHolder = new ChainHolder())
                    using (var offlineChainHolder = new ChainHolder())
                    {
                        X509Chain onlineChain  = onlineChainHolder.Chain;
                        X509Chain offlineChain = offlineChainHolder.Chain;

                        onlineChain.ChainPolicy.VerificationFlags =
                            X509VerificationFlags.AllowUnknownCertificateAuthority;

                        onlineChain.ChainPolicy.VerificationTime = cert.NotBefore.AddHours(2);
                        onlineChain.ChainPolicy.RevocationMode   = X509RevocationMode.Online;
                        onlineChain.ChainPolicy.RevocationFlag   = X509RevocationFlag.EntireChain;

                        bool valid = onlineChain.Build(cert);
                        Assert.True(valid, "Online Chain Built Validly");

                        // Since the network was enabled, we should get the whole chain.
                        Assert.Equal(3, onlineChain.ChainElements.Count);

                        Assert.Equal(0, onlineChain.ChainElements[0].ChainElementStatus.Length);
                        Assert.Equal(0, onlineChain.ChainElements[1].ChainElementStatus.Length);

                        // The root CA is not expected to be installed on everyone's machines,
                        // so allow for it to report UntrustedRoot, but nothing else..
                        X509ChainStatus[] rootElementStatus = onlineChain.ChainElements[2].ChainElementStatus;

                        if (rootElementStatus.Length != 0)
                        {
                            Assert.Equal(1, rootElementStatus.Length);
                            Assert.Equal(X509ChainStatusFlags.UntrustedRoot, rootElementStatus[0].Status);
                        }

                        // Now that everything is cached, try again in Offline mode.
                        offlineChain.ChainPolicy.VerificationFlags = onlineChain.ChainPolicy.VerificationFlags;
                        offlineChain.ChainPolicy.VerificationTime  = onlineChain.ChainPolicy.VerificationTime;
                        offlineChain.ChainPolicy.RevocationMode    = X509RevocationMode.Offline;
                        offlineChain.ChainPolicy.RevocationFlag    = onlineChain.ChainPolicy.RevocationFlag;

                        valid = offlineChain.Build(cert);
                        Assert.True(valid, "Offline Chain Built Validly");

                        // Everything should look just like the online chain:
                        Assert.Equal(onlineChain.ChainElements.Count, offlineChain.ChainElements.Count);

                        for (int i = 0; i < offlineChain.ChainElements.Count; i++)
                        {
                            X509ChainElement onlineElement  = onlineChain.ChainElements[i];
                            X509ChainElement offlineElement = offlineChain.ChainElements[i];

                            Assert.Equal(onlineElement.ChainElementStatus, offlineElement.ChainElementStatus);
                            Assert.Equal(onlineElement.Certificate, offlineElement.Certificate);
                        }
                    }
        }
예제 #19
0
        private static bool HasUnsuppressedError(X509VerificationFlags flags, X509ChainElement element, bool isEndEntity)
        {
            foreach (X509ChainStatus status in element.ChainElementStatus)
            {
                if (status.Status == X509ChainStatusFlags.NoError)
                {
                    return(false);
                }

                Debug.Assert(
                    (status.Status & (status.Status - 1)) == 0,
                    $"Only one bit should be set in status.Status ({status})");

                // The Windows certificate store API only checks the time error for a "peer trust" certificate,
                // but we don't have a concept for that in Unix.  If we did, we'd need to do that logic that here.
                // Note also that the logic is skipped if CERT_CHAIN_POLICY_IGNORE_PEER_TRUST_FLAG is set.

                X509VerificationFlags?suppressionFlag;

                if (status.Status == X509ChainStatusFlags.RevocationStatusUnknown)
                {
                    if (isEndEntity)
                    {
                        suppressionFlag = X509VerificationFlags.IgnoreEndRevocationUnknown;
                    }
                    else if (IsSelfSigned(element.Certificate))
                    {
                        suppressionFlag = X509VerificationFlags.IgnoreRootRevocationUnknown;
                    }
                    else
                    {
                        suppressionFlag = X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown;
                    }
                }
                else if (status.Status == X509ChainStatusFlags.OfflineRevocation)
                {
                    // This is mainly a warning code, it's redundant to RevocationStatusUnknown
                    continue;
                }
                else
                {
                    suppressionFlag = GetSuppressionFlag(status.Status);
                }

                // If an error was found, and we do NOT have the suppression flag for it enabled,
                // we have an unsuppressed error, so return true. (If there's no suppression for a given code,
                // we (by definition) don't have that flag set.
                if (!suppressionFlag.HasValue ||
                    (flags & suppressionFlag) == 0)
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #20
0
        private static void AssertChainHasNoProblems(X509ChainElement chainElement)
        {
            X509ChainStatus[] chainElementStatus = chainElement.ChainElementStatus;
            Assert.False(chainElementStatus.IsNullOrEmpty(), "Missing chain status elements.");

            foreach (var chainElementStatu in chainElementStatus)
            {
                Assert.False((chainElementStatu.Status & DefaultProblemFlags) != 0);
            }
        }
        // Verifies that a chain of trust can be built from the health report provided
        // by SQL Server and the attestation service's root signing certificate(s).
        private X509ChainStatusFlags VerifyHealthReportAgainstRootCertificate(X509Certificate2Collection signingCerts, X509Certificate2 healthReportCert)
        {
            var chain = new X509Chain();

            foreach (var cert in signingCerts)
            {
                chain.ChainPolicy.ExtraStore.Add(cert);
            }

            chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;

            if (!chain.Build(healthReportCert))
            {
                bool untrustedRoot = false;

                // iterate over the chain status to check why the build failed
                foreach (X509ChainStatus status in chain.ChainStatus)
                {
                    if (status.Status == X509ChainStatusFlags.UntrustedRoot)
                    {
                        untrustedRoot = true;
                    }
                    else
                    {
                        return(status.Status);
                    }
                }

                // if the chain failed with untrusted root, this could be because the client doesn't have the root cert
                // installed. If the chain's untrusted root cert has the same thumbprint as the signing cert, then we
                // do trust it.
                if (untrustedRoot)
                {
                    // iterate through the certificate chain, starting at the root since it's likely the
                    // signing certificate is the root
                    for (int i = 0; i < chain.ChainElements.Count; i++)
                    {
                        X509ChainElement element = chain.ChainElements[chain.ChainElements.Count - 1 - i];

                        foreach (X509Certificate2 cert in signingCerts)
                        {
                            if (element.Certificate.Thumbprint == cert.Thumbprint)
                            {
                                return(X509ChainStatusFlags.NoError);
                            }
                        }
                    }

                    // in the case where we didn't find matching thumbprint
                    return(X509ChainStatusFlags.UntrustedRoot);
                }
            }

            return(X509ChainStatusFlags.NoError);
        }
예제 #22
0
 void extendedCertValidation(TreeNode <ChainElement> tree, X509ChainElement chainElement, Int32 index)
 {
     if (Settings.Default.CheckWeakPubKey)
     {
         if (chainElement.Certificate.PublicKey.Oid.Value == "1.2.840.113549.1.1.1")
         {
             if (chainElement.Certificate.PublicKey.Key.KeySize < Settings.Default.MinimumPubKeyLength)
             {
                 addStatus(tree.Value, new[] { new X509ChainStatus {
                                                   Status = (X509ChainStatusFlags)X509ChainStatusFlags2.WeakRsaPublicKey
                                               } });
             }
         }
     }
     if (Settings.Default.CheckWeakPubKey)
     {
         Boolean isRoot = chainElement.Certificate.SubjectName.RawData.SequenceEqual(chainElement.Certificate.IssuerName.RawData);
         if (!isRoot)
         {
             if (Settings.Default.WeakAlgs.Contains(chainElement.Certificate.SignatureAlgorithm.Value))
             {
                 addStatus(tree.Value, new[] { new X509ChainStatus {
                                                   Status = (X509ChainStatusFlags)X509ChainStatusFlags2.WeakSignatureAlgorithm
                                               } });
             }
         }
         if (chainElement.Certificate.PublicKey.Oid.Value == "1.2.840.113549.1.1.1")
         {
             if (chainElement.Certificate.PublicKey.Key.KeySize < Settings.Default.MinimumPubKeyLength)
             {
                 addStatus(tree.Value, new[] { new X509ChainStatus {
                                                   Status = (X509ChainStatusFlags)X509ChainStatusFlags2.WeakRsaPublicKey
                                               } });
             }
         }
     }
     if ((chainElement.Certificate.NotAfter - DateTime.Now).Days <= threshold)
     {
         addStatus(tree.Value, new[] { new X509ChainStatus {
                                           Status = (X509ChainStatusFlags)X509ChainStatusFlags2.AboutExpire
                                       } });
     }
     if (index == 0)
     {
         if (!hasValidEKU(chainElement.Certificate))
         {
             if ((chainElement.Certificate.NotAfter - DateTime.Now).Days <= threshold)
             {
                 addStatus(tree.Value, new[] { new X509ChainStatus {
                                                   Status = (X509ChainStatusFlags)X509ChainStatusFlags2.NotValidForUsage
                                               } });
             }
         }
     }
 }
                protected override void EstablishContext()
                {
                    base.EstablishContext();

                    var collection = new X509Chain();

                    collection.Build(new X509Certificate2(LiebherrRootCaCertificateRawCertData));
                    this.SpecifiedElement = collection.ChainElements[0];

                    this.ExpectedSubject = "CN=LiebherrRootCA, OU=ZEDV-ORG, O=Liebherr, C=DE";
                }
예제 #24
0
 private void NotifyProblem(X509ChainElement chainElement)
 {
     if (this.Problem != null)
     {
         try
         {
             this.Problem(chainElement);
         }
         catch
         {
         }
     }
 }
예제 #25
0
        private static void AssertChainHasProblems(X509ChainElement chainElement)
        {
            X509ChainStatus[] chainElementStatus = chainElement.ChainElementStatus;
            Assert.False(chainElementStatus.IsNullOrEmpty(), "Missing chain status elements.");

            foreach (var chainElementStatu in chainElementStatus)
            {
                if ((chainElementStatu.Status & DefaultProblemFlags) != 0)
                {
                    return;  //we expect problems
                }
            }
            Assert.True(false, "Expected chain problems and found none.");
        }
예제 #26
0
        private bool ChainElementHasProblems(X509ChainElement chainElement)
        {
            // If the builder finds problems with the cert, it will provide a list of "status" flags for the cert
            X509ChainStatus[] chainElementStatus = chainElement.ChainElementStatus;

            // If the list is empty or the list is null, then there were NO problems with the cert
            if (chainElementStatus.IsNullOrEmpty())
            {
                return(false);
            }

            // Return true if there are any status flags we care about
            return(chainElementStatus.Any(s => (s.Status & ProblemFlags) != 0));
        }
예제 #27
0
        private Org.BouncyCastle.X509.X509Certificate[] GetCertChain(X509Certificate2 cert)
        {
            Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();
            X509Chain ch = new X509Chain();

            //ch.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
            ch.Build(cert);
            Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[ch.ChainElements.Count];
            for (int idx = 0; idx < ch.ChainElements.Count; idx++)
            {
                X509ChainElement chElem = ch.ChainElements[idx];
                chain[idx] = cp.ReadCertificate(chElem.Certificate.RawData);
            }
            return(chain);
        }
예제 #28
0
 public static Int32 IndexOf(this X509ChainElementCollection collection, X509ChainElement item)
 {
     if (collection == null)
     {
         return(-1);
     }
     for (Int32 index = 0; index < collection.Count; index++)
     {
         if (collection[index].Certificate.Equals(item.Certificate))
         {
             return(index);
         }
     }
     return(-1);
 }
        public KeyInfoX509Data(X509Certificate cert, X509IncludeOption includeOption)
        {
            if (cert == null)
            {
                throw new ArgumentNullException("cert");
            }
            X509Certificate2           certificate   = new X509Certificate2(cert);
            X509ChainElementCollection chainElements = null;
            X509Chain chain = null;

            switch (includeOption)
            {
            case X509IncludeOption.ExcludeRoot:
                chain = new X509Chain();
                chain.Build(certificate);
                if ((chain.ChainStatus.Length > 0) && ((chain.ChainStatus[0].Status & X509ChainStatusFlags.PartialChain) == X509ChainStatusFlags.PartialChain))
                {
                    throw new CryptographicException(-2146762486);
                }
                chainElements = chain.ChainElements;
                for (int i = 0; i < (System.Security.Cryptography.X509Certificates.X509Utils.IsSelfSigned(chain) ? 1 : (chainElements.Count - 1)); i++)
                {
                    this.AddCertificate(chainElements[i].Certificate);
                }
                return;

            case X509IncludeOption.EndCertOnly:
                this.AddCertificate(certificate);
                return;

            case X509IncludeOption.WholeChain:
            {
                chain = new X509Chain();
                chain.Build(certificate);
                if ((chain.ChainStatus.Length > 0) && ((chain.ChainStatus[0].Status & X509ChainStatusFlags.PartialChain) == X509ChainStatusFlags.PartialChain))
                {
                    throw new CryptographicException(-2146762486);
                }
                X509ChainElementEnumerator enumerator = chain.ChainElements.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    X509ChainElement current = enumerator.Current;
                    this.AddCertificate(current.Certificate);
                }
                return;
            }
            }
        }
예제 #30
0
        //this code comes from AgentDiagnostics.  Need a better way to hook ino Agent.
        //Agent hooks TrustChainValidator and the build in DnsCertResolver, but the DnsCertResolver is strongly
        //linked rather than via interface for notifications and exceptions.
        static string Summarize(X509ChainElement chainElement, X509ChainStatusFlags problemFlags)
        {
            StringBuilder builder = new StringBuilder();

            builder.Append(chainElement.Certificate.ExtractEmailNameOrName());
            builder.Append(";");
            foreach (X509ChainStatus status in chainElement.ChainElementStatus)
            {
                if ((status.Status & problemFlags) != 0)
                {
                    builder.Append(status.Status);
                }
            }

            return(builder.ToString());
        }
 public void CopyTo(X509ChainElement[] array, int index);