public virtual async Task <IValidationResult> ValidateAsync(ICertificate certificate, CertificateValidatorOptions options)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            var validationResult = new ValidationResult();

            var isSelfSignedCertificate = this.IsSelfSignedCertificate(certificate);

            if (isSelfSignedCertificate && !options.AllowedCertificateKinds.HasFlag(CertificateKinds.SelfSigned))
            {
                validationResult.Exceptions.Add(new InvalidOperationException("Options do not allow self signed certificates."));
            }

            // ReSharper disable InvertIf
            if (validationResult.Valid)
            {
                if (!isSelfSignedCertificate && !options.AllowedCertificateKinds.HasFlag(CertificateKinds.Chained))
                {
                    validationResult.Exceptions.Add(new InvalidOperationException("Options do not allow chained certificates."));
                }

                if (validationResult.Valid)
                {
                    var validationOptions = isSelfSignedCertificate ? options.SelfSigned : options.Chained;
                    var chain             = this.CreateChain(certificate, validationOptions);

                    //// Can not find any reason to add it to the extra store.
                    //if (isSelfSignedCertificate)
                    //	chain.ChainPolicy.ExtraStore.Add(this.UnwrapCertificate(certificate));

                    if (!chain.Build(this.UnwrapCertificate(certificate)))
                    {
                        foreach (var chainStatus in chain.ChainStatus)
                        {
                            validationResult.Exceptions.Add(new InvalidOperationException($"{chainStatus.Status}: {chainStatus.StatusInformation}"));
                        }

                        foreach (var chainLink in chain.ChainElements)
                        {
                            foreach (var chainStatus in chainLink.ChainElementStatus)
                            {
                                validationResult.Exceptions.Add(new InvalidOperationException($"{chainLink.Certificate.Subject}: {chainStatus.Status} - {chainStatus.StatusInformation}"));
                            }
                        }
                    }

                    if (validationOptions.CustomTrustChecking)
                    {
                        var certificates = chain.ChainElements.Cast <X509ChainElement>().Select(element => (X509Certificate2Wrapper)element.Certificate).ToArray();

                        var intermediateCertificates = certificates.Take(certificates.Length - 1).Skip(1).ToArray();

                        foreach (var intermediateCertificate in intermediateCertificates)
                        {
                            if (!validationOptions.TrustedIntermediateCertificates.Contains(intermediateCertificate))
                            {
                                validationResult.Exceptions.Add(new InvalidOperationException($"{certificate.Subject}: {nameof(validationOptions.CustomTrustChecking)} is set to {validationOptions.CustomTrustChecking} and the intermediate-certificate \"{intermediateCertificate.Subject}\" is not in the list of trusted intermediate-certificates."));
                            }
                        }

                        var rootCertificate = certificates.Last();

                        if (!validationOptions.TrustedRootCertificates.Contains(rootCertificate))
                        {
                            validationResult.Exceptions.Add(new InvalidOperationException($"{certificate.Subject}: {nameof(validationOptions.CustomTrustChecking)} is set to {validationOptions.CustomTrustChecking} and the root-certificate \"{rootCertificate.Subject}\" is not in the list of trusted root-certificates."));
                        }
                    }

                    if (validationResult.Valid)
                    {
                        validationResult.Exceptions.Add(this.EvaluateMatching(certificate, validationOptions).Exceptions);
                    }
                }
            }
            // ReSharper restore InvertIf

            return(await Task.FromResult(validationResult).ConfigureAwait(false));
        }
 public virtual async Task <IValidationResult> ValidateAsync(X509Certificate2 certificate, CertificateValidatorOptions options)
 {
     return(await this.ValidateAsync((X509Certificate2Wrapper)certificate, options).ConfigureAwait(false));
 }
        public static IValidationResult Validate(this ICertificateValidator certificateValidator, X509Certificate2 certificate, CertificateValidatorOptions options)
        {
            if (certificateValidator == null)
            {
                throw new ArgumentNullException(nameof(certificateValidator));
            }

            return(certificateValidator.ValidateAsync(certificate, options).Result);
        }