private CertificateVerificationResult VerifyCertificate(X509Certificate2 certificate, IReadOnlyList <X509Certificate2> extraCertificates, Oid applicationPolicy)
        {
            X509Chain chain = null;

            try
            {
                chain = new X509Chain();

                // Allow the chain to use whatever additional extra certificates were provided.
                chain.ChainPolicy.ExtraStore.AddRange(extraCertificates.ToArray());

                if (applicationPolicy != null)
                {
                    chain.ChainPolicy.ApplicationPolicy.Add(applicationPolicy);
                }

                chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
                chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;

                var resultBuilder = new CertificateVerificationResult.Builder();

                if (chain.Build(certificate))
                {
                    resultBuilder.WithStatus(EndCertificateStatus.Good);
                    resultBuilder.WithStatusFlags(X509ChainStatusFlags.NoError);
                }
                else
                {
                    resultBuilder.WithStatus(GetEndCertificateStatusFromInvalidChain(chain));
                    resultBuilder.WithStatusFlags(FlattenChainStatusFlags(chain));
                }

                InspectChain(chain, certificate, resultBuilder);

                return(resultBuilder.Build());
            }
            finally
            {
                if (chain != null)
                {
                    foreach (var chainElement in chain.ChainElements)
                    {
                        chainElement.Certificate.Dispose();
                    }

                    chain.Dispose();
                }
            }
        }
        private unsafe void InspectChain(X509Chain chain, X509Certificate2 certificate, CertificateVerificationResult.Builder resultBuilder)
        {
            var addedRef    = false;
            var chainHandle = chain.SafeHandle;

            try
            {
                chainHandle.DangerousAddRef(ref addedRef);

                CERT_REVOCATION_INFO *pRevocationInfo = GetEndCertificateRevocationInfoPointer(chainHandle, certificate);

                if (CertificateWasVerifiedOnline(pRevocationInfo))
                {
                    resultBuilder.WithRevocationTime(GetRevocationTime(pRevocationInfo));
                    resultBuilder.WithStatusUpdateTime(GetStatusUpdateTime(pRevocationInfo));
                }
            }
            finally
            {
                if (addedRef)
                {
                    chainHandle.DangerousRelease();
                }
            }
        }