Esempio n. 1
0
        public static void CertificatePolicy_Roundtrips()
        {
            ICertificatePolicy cp = ServicePointManager.CertificatePolicy;

            Assert.NotNull(cp);

            Assert.True(cp.CheckValidationResult(null, null, null, 0));
            Assert.False(cp.CheckValidationResult(null, null, null, 1));

            ServicePointManager.CertificatePolicy = null;
            Assert.Null(ServicePointManager.CertificatePolicy);

            ServicePointManager.CertificatePolicy = cp;
            Assert.Same(cp, ServicePointManager.CertificatePolicy);
        }
        public static void CertificatePolicy_Roundtrips()
        {
#pragma warning disable CS0618 // obsolete warnings
            ICertificatePolicy cp = ServicePointManager.CertificatePolicy;
            Assert.NotNull(cp);

            Assert.True(cp.CheckValidationResult(null, null, null, 0));
            Assert.False(cp.CheckValidationResult(null, null, null, 1));

            ServicePointManager.CertificatePolicy = null;
            Assert.Null(ServicePointManager.CertificatePolicy);

            ServicePointManager.CertificatePolicy = cp;
            Assert.Same(cp, ServicePointManager.CertificatePolicy);
#pragma warning restore CS0619
        }
Esempio n. 3
0
        /// <summary>Returns true if we have registered the certificate.  Calls the
        /// next ICertificatePolicy if we fail.</summary>
        public bool CheckValidationResult(ServicePoint service_point,
                                          X509Certificate cert, WebRequest request, int cert_problem)
        {
            MemBlock blob = MemBlock.Reference(cert.GetRawCertData());

            if (_certs.Contains(blob))
            {
                return(true);
            }
            if (_old_policy != null)
            {
                return(_old_policy.CheckValidationResult(service_point, cert,
                                                         request, cert_problem));
            }
            return(false);
        }
Esempio n. 4
0
            // Used when the obsolete ICertificatePolicy is set to DefaultCertificatePolicy
            // and the new ServerCertificateValidationCallback is not null
            internal ValidationResult ValidateChain(Mono.Security.X509.X509CertificateCollection certs)
            {
                // user_denied is true if the user callback is called and returns false
                bool user_denied = false;

                if (certs == null || certs.Count == 0)
                {
                    return(null);
                }

                ICertificatePolicy policy = ServicePointManager.CertificatePolicy;
                RemoteCertificateValidationCallback cb = ServicePointManager.ServerCertificateValidationCallback;

                X509Chain chain = new X509Chain();

                chain.ChainPolicy = new X509ChainPolicy();
                for (int i = 1; i < certs.Count; i++)
                {
                    X509Certificate2 c2 = new X509Certificate2(certs [i].RawData);
                    chain.ChainPolicy.ExtraStore.Add(c2);
                }

                X509Certificate2 leaf    = new X509Certificate2(certs [0].RawData);
                int             status11 = 0;     // Error code passed to the obsolete ICertificatePolicy callback
                SslPolicyErrors errors   = 0;

                try {
                    if (!chain.Build(leaf))
                    {
                        errors |= GetErrorsFromChain(chain);
                    }
                } catch (Exception e) {
                    Console.Error.WriteLine("ERROR building certificate chain: {0}", e);
                    Console.Error.WriteLine("Please, report this problem to the Mono team");
                    errors |= SslPolicyErrors.RemoteCertificateChainErrors;
                }

                if (!CheckCertificateUsage(leaf))
                {
                    errors  |= SslPolicyErrors.RemoteCertificateChainErrors;
                    status11 = -2146762490;                     //CERT_E_PURPOSE 0x800B0106
                }

                if (!CheckServerIdentity(certs [0], Host))
                {
                    errors  |= SslPolicyErrors.RemoteCertificateNameMismatch;
                    status11 = -2146762481;                     // CERT_E_CN_NO_MATCH 0x800B010F
                }

                bool result = false;

                // No certificate root found means no mozroots or monotouch
#if !MONOTOUCH
                if (is_macosx)
                {
#endif
                // Attempt to use OSX certificates
                // Ideally we should return the SecTrustResult
                MSX.OSX509Certificates.SecTrustResult trustResult;
                try {
                    trustResult = MSX.OSX509Certificates.TrustEvaluateSsl(certs);
                    // We could use the other values of trustResult to pass this extra information
                    // to the .NET 2 callback for values like SecTrustResult.Confirm
                    result = (trustResult == MSX.OSX509Certificates.SecTrustResult.Proceed ||
                              trustResult == MSX.OSX509Certificates.SecTrustResult.Unspecified);
                }
                catch {
                    // Ignore
                }
                // Clear error status if the OS told us to trust the certificate
                if (result)
                {
                    status11 = 0;
                    errors   = 0;
                }
#if !MONOTOUCH
            }
#endif

                if (policy != null && (!(policy is DefaultCertificatePolicy) || cb == null))
                {
                    ServicePoint   sp  = null;
                    HttpWebRequest req = sender as HttpWebRequest;
                    if (req != null)
                    {
                        sp = req.ServicePoint;
                    }
                    if (status11 == 0 && errors != 0)
                    {
                        status11 = GetStatusFromChain(chain);
                    }

                    // pre 2.0 callback
                    result      = policy.CheckValidationResult(sp, leaf, req, status11);
                    user_denied = !result && !(policy is DefaultCertificatePolicy);
                }
                // If there's a 2.0 callback, it takes precedence
                if (cb != null)
                {
                    result      = cb(sender, leaf, chain, errors);
                    user_denied = !result;
                }
                return(new ValidationResult(result, user_denied, status11));
            }
Esempio n. 5
0
        ValidationResult ValidateChain(string host, bool server, X509Certificate leaf,
                                       ref X509Chain chain, X509CertificateCollection certs,
                                       SslPolicyErrors errors)
        {
            // user_denied is true if the user callback is called and returns false
            bool user_denied = false;
            bool result      = false;

            var hasCallback = certValidationCallback != null || callbackWrapper != null;

            if (tlsStream != null)
            {
                request.ServicePoint.UpdateServerCertificate(leaf);
            }

            if (leaf == null)
            {
                errors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                if (hasCallback)
                {
                    if (callbackWrapper != null)
                    {
                        result = callbackWrapper.Invoke(certValidationCallback, leaf, null, (MonoSslPolicyErrors)errors);
                    }
                    else
                    {
                        result = certValidationCallback.Invoke(sender, leaf, null, errors);
                    }
                    user_denied = !result;
                }
                return(new ValidationResult(result, user_denied, 0, (MonoSslPolicyErrors)errors));
            }

            // Ignore port number when validating certificates.
            if (!string.IsNullOrEmpty(host))
            {
                var pos = host.IndexOf(':');
                if (pos > 0)
                {
                    host = host.Substring(0, pos);
                }
            }

            ICertificatePolicy policy = ServicePointManager.GetLegacyCertificatePolicy();

            int status11 = 0;             // Error code passed to the obsolete ICertificatePolicy callback

            bool wantsChain = SystemCertificateValidator.NeedsChain(settings);

            if (!wantsChain && hasCallback)
            {
                if (settings == null || settings.CallbackNeedsCertificateChain)
                {
                    wantsChain = true;
                }
            }

            var xerrors = (MonoSslPolicyErrors)errors;

            result = provider.ValidateCertificate(this, host, server, certs, wantsChain, ref chain, ref xerrors, ref status11);
            errors = (SslPolicyErrors)xerrors;

            if (status11 == 0 && errors != 0)
            {
                // TRUST_E_FAIL
                status11 = unchecked ((int)0x800B010B);
            }

            if (policy != null && (!(policy is DefaultCertificatePolicy) || certValidationCallback == null))
            {
                ServicePoint sp = null;
                if (request != null)
                {
                    sp = request.ServicePointNoLock;
                }

                // pre 2.0 callback
                result      = policy.CheckValidationResult(sp, leaf, request, status11);
                user_denied = !result && !(policy is DefaultCertificatePolicy);
            }
            // If there's a 2.0 callback, it takes precedence
            if (hasCallback)
            {
                if (callbackWrapper != null)
                {
                    result = callbackWrapper.Invoke(certValidationCallback, leaf, chain, (MonoSslPolicyErrors)errors);
                }
                else
                {
                    result = certValidationCallback.Invoke(sender, leaf, chain, errors);
                }
                user_denied = !result;
            }
            return(new ValidationResult(result, user_denied, status11, (MonoSslPolicyErrors)errors));
        }
        ValidationResult ValidateChain(string host, bool server, XX509CertificateCollection certs, SslPolicyErrors errors)
        {
            // user_denied is true if the user callback is called and returns false
            bool user_denied = false;
            bool result      = false;

            var hasCallback = certValidationCallback != null || callbackWrapper != null;

            X509Certificate leaf;

            if (certs == null || certs.Count == 0)
            {
                leaf = null;
            }
            else
            {
                leaf = certs [0];
            }

            if (tlsStream != null)
            {
                request.ServicePoint.SetServerCertificate(leaf);
            }

            if (leaf == null)
            {
                errors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                if (hasCallback)
                {
                    if (callbackWrapper != null)
                    {
                        result = callbackWrapper.Invoke(certValidationCallback, leaf, null, (MonoSslPolicyErrors)errors);
                    }
                    else
                    {
                        result = certValidationCallback.Invoke(sender, leaf, null, errors);
                    }
                    user_denied = !result;
                }
                return(new ValidationResult(result, user_denied, 0, (MonoSslPolicyErrors)errors));
            }

            ICertificatePolicy policy = ServicePointManager.GetLegacyCertificatePolicy();

            int       status11 = 0;       // Error code passed to the obsolete ICertificatePolicy callback
            X509Chain chain    = null;

            bool wantsChain = SystemCertificateValidator.NeedsChain(settings);

            if (!wantsChain && hasCallback)
            {
                if (settings == null || settings.CallbackNeedsCertificateChain)
                {
                    wantsChain = true;
                }
            }

            if (wantsChain)
            {
                chain = SystemCertificateValidator.CreateX509Chain(certs);
            }

            if (wantsChain || SystemCertificateValidator.NeedsChain(settings))
            {
                SystemCertificateValidator.BuildX509Chain(certs, chain, ref errors, ref status11);
            }

            bool providerValidated = false;

            if (provider != null && provider.HasCustomSystemCertificateValidator)
            {
                var xerrors = (MonoSslPolicyErrors)errors;
                var xchain  = (XX509Chain)(object)chain;
                providerValidated = provider.InvokeSystemCertificateValidator(this, host, server, certs, xchain, out result, ref xerrors, ref status11);
                errors            = (SslPolicyErrors)xerrors;
            }

            if (!providerValidated)
            {
                result = SystemCertificateValidator.Evaluate(settings, host, certs, chain, ref errors, ref status11);
            }

            if (policy != null && (!(policy is DefaultCertificatePolicy) || certValidationCallback == null))
            {
                ServicePoint sp = null;
                if (request != null)
                {
                    sp = request.ServicePointNoLock;
                }
                if (status11 == 0 && errors != 0)
                {
                    // TRUST_E_FAIL
                    status11 = unchecked ((int)0x800B010B);
                }

                // pre 2.0 callback
                result      = policy.CheckValidationResult(sp, leaf, request, status11);
                user_denied = !result && !(policy is DefaultCertificatePolicy);
            }
            // If there's a 2.0 callback, it takes precedence
            if (hasCallback)
            {
                if (callbackWrapper != null)
                {
                    result = callbackWrapper.Invoke(certValidationCallback, leaf, chain, (MonoSslPolicyErrors)errors);
                }
                else
                {
                    result = certValidationCallback.Invoke(sender, leaf, chain, errors);
                }
                user_denied = !result;
            }
            return(new ValidationResult(result, user_denied, status11, (MonoSslPolicyErrors)errors));
        }
Esempio n. 7
0
            // Used when the obsolete ICertificatePolicy is set to DefaultCertificatePolicy
            // and the new ServerCertificateValidationCallback is not null
            internal ValidationResult ValidateChain(MSX.X509CertificateCollection certs)
            {
                // user_denied is true if the user callback is called and returns false
                bool user_denied = false;

                if (certs == null || certs.Count == 0)
                {
                    return(null);
                }

                ICertificatePolicy policy = ServicePointManager.CertificatePolicy;

                X509Certificate2 leaf    = new X509Certificate2(certs [0].RawData);
                int             status11 = 0;     // Error code passed to the obsolete ICertificatePolicy callback
                SslPolicyErrors errors   = 0;
                X509Chain       chain    = null;
                bool            result   = false;

#if MONOTOUCH
                // The X509Chain is not really usable with MonoTouch (since the decision is not based on this data)
                // However if someone wants to override the results (good or bad) from iOS then they will want all
                // the certificates that the server provided (which generally does not include the root) so, only
                // if there's a user callback, we'll create the X509Chain but won't build it
                // ref: https://bugzilla.xamarin.com/show_bug.cgi?id=7245
                if (ServerCertificateValidationCallback != null)
                {
#endif
                chain             = new X509Chain();
                chain.ChainPolicy = new X509ChainPolicy();
#if !MONOTOUCH
                chain.ChainPolicy.RevocationMode = revocation_mode;
#endif
                for (int i = 1; i < certs.Count; i++)
                {
                    X509Certificate2 c2 = new X509Certificate2(certs [i].RawData);
                    chain.ChainPolicy.ExtraStore.Add(c2);
                }
#if MONOTOUCH
            }
#else
                try {
                    if (!chain.Build(leaf))
                    {
                        errors |= GetErrorsFromChain(chain);
                    }
                } catch (Exception e) {
                    Console.Error.WriteLine("ERROR building certificate chain: {0}", e);
                    Console.Error.WriteLine("Please, report this problem to the Mono team");
                    errors |= SslPolicyErrors.RemoteCertificateChainErrors;
                }

                // for OSX and iOS we're using the native API to check for the SSL server policy and host names
                if (!is_macosx)
                {
                    if (!CheckCertificateUsage(leaf))
                    {
                        errors  |= SslPolicyErrors.RemoteCertificateChainErrors;
                        status11 = -2146762490;                         //CERT_E_PURPOSE 0x800B0106
                    }

                    if (!CheckServerIdentity(certs [0], host))
                    {
                        errors  |= SslPolicyErrors.RemoteCertificateNameMismatch;
                        status11 = -2146762481;                         // CERT_E_CN_NO_MATCH 0x800B010F
                    }
                }
                else
                {
#endif
            // Attempt to use OSX certificates
            // Ideally we should return the SecTrustResult
            OSX509Certificates.SecTrustResult trustResult = OSX509Certificates.SecTrustResult.Deny;
            try {
                trustResult = OSX509Certificates.TrustEvaluateSsl(certs, host);
                // We could use the other values of trustResult to pass this extra information
                // to the .NET 2 callback for values like SecTrustResult.Confirm
                result = (trustResult == OSX509Certificates.SecTrustResult.Proceed ||
                          trustResult == OSX509Certificates.SecTrustResult.Unspecified);
            } catch {
                // Ignore
            }

            if (result)
            {
                // TrustEvaluateSsl was successful so there's no trust error
                // IOW we discard our own chain (since we trust OSX one instead)
                errors = 0;
            }
            else
            {
                // callback and DefaultCertificatePolicy needs this since 'result' is not specified
                status11 = (int)trustResult;
                errors  |= SslPolicyErrors.RemoteCertificateChainErrors;
            }
#if !MONOTOUCH
        }
#endif

#if MONODROID && SECURITY_DEP
            result = AndroidPlatform.TrustEvaluateSsl(certs, sender, leaf, chain, errors);
            if (result)
            {
                // chain.Build() + GetErrorsFromChain() (above) will ALWAYS fail on
                // Android (there are no mozroots or preinstalled root certificates),
                // thus `errors` will ALWAYS have RemoteCertificateChainErrors.
                // Android just verified the chain; clear RemoteCertificateChainErrors.
                errors &= ~SslPolicyErrors.RemoteCertificateChainErrors;
            }
#endif

            if (policy != null && (!(policy is DefaultCertificatePolicy) || cb == null))
            {
                ServicePoint   sp  = null;
                HttpWebRequest req = sender as HttpWebRequest;
                if (req != null)
                {
                    sp = req.ServicePointNoLock;
                }
                if (status11 == 0 && errors != 0)
                {
                    status11 = GetStatusFromChain(chain);
                }

                // pre 2.0 callback
                result      = policy.CheckValidationResult(sp, leaf, req, status11);
                user_denied = !result && !(policy is DefaultCertificatePolicy);
            }
            // If there's a 2.0 callback, it takes precedence
            if (ServerCertificateValidationCallback != null)
            {
                result      = ServerCertificateValidationCallback(sender, leaf, chain, errors);
                user_denied = !result;
            }
            return(new ValidationResult(result, user_denied, status11));
        }
Esempio n. 8
0
        ValidationResult ValidateChain(string host, X509Certificate2Collection certs, SslPolicyErrors errors)
        {
            // user_denied is true if the user callback is called and returns false
            bool user_denied = false;
            bool result      = false;

            var hasCallback = certValidationCallback != null || callbackWrapper != null;

            X509Certificate2 leaf;

            if (certs == null || certs.Count == 0)
            {
                leaf = null;
            }
            else
            {
                leaf = certs [0];
            }

            if (tlsStream != null)
            {
                request.ServicePoint.SetServerCertificate(leaf);
            }

            if (leaf == null)
            {
                errors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                if (hasCallback)
                {
                    if (callbackWrapper != null)
                    {
                        result = callbackWrapper.Invoke(certValidationCallback, leaf, null, (MonoSslPolicyErrors)errors);
                    }
                    else
                    {
                        result = certValidationCallback.Invoke(sender, leaf, null, errors);
                    }
                    user_denied = !result;
                }
                return(new ValidationResult(result, user_denied, 0, (MonoSslPolicyErrors)errors));
            }

            bool needsChain;
            bool skipSystemValidators = false;

            if (!CertificateValidationHelper.SupportsX509Chain || is_mobile || is_macosx)
            {
                needsChain = false;
            }
            else if (settings != null)
            {
                skipSystemValidators = settings.SkipSystemValidators;
                needsChain           = !settings.SkipSystemValidators || settings.CallbackNeedsCertificateChain;
            }
            else
            {
                needsChain = true;
            }

            ICertificatePolicy policy = ServicePointManager.GetLegacyCertificatePolicy();

            int       status11 = 0;       // Error code passed to the obsolete ICertificatePolicy callback
            X509Chain chain    = null;

            if (needsChain)
            {
                chain             = new X509Chain();
                chain.ChainPolicy = new X509ChainPolicy();


#if !MONOTOUCH
                chain.ChainPolicy.RevocationMode = revocation_mode;
#endif
                for (int i = 1; i < certs.Count; i++)
                {
                    chain.ChainPolicy.ExtraStore.Add(certs [i]);
                }
            }

#if !MONOTOUCH
            if (needsChain)
            {
                try {
                    if (!chain.Build(leaf))
                    {
                        errors |= GetErrorsFromChain(chain);
                    }
                } catch (Exception e) {
                    Console.Error.WriteLine("ERROR building certificate chain: {0}", e);
                    Console.Error.WriteLine("Please, report this problem to the Mono team");
                    errors |= SslPolicyErrors.RemoteCertificateChainErrors;
                }
            }

            // for OSX and iOS we're using the native API to check for the SSL server policy and host names
            if (!is_macosx)
            {
                if (!CheckCertificateUsage(leaf))
                {
                    errors  |= SslPolicyErrors.RemoteCertificateChainErrors;
                    status11 = -2146762490;                     //CERT_E_PURPOSE 0x800B0106
                }

                if (host != null && !CheckServerIdentity(leaf, host))
                {
                    errors  |= SslPolicyErrors.RemoteCertificateNameMismatch;
                    status11 = -2146762481;                     // CERT_E_CN_NO_MATCH 0x800B010F
                }
            }
#endif

            if (is_macosx && !skipSystemValidators)
            {
                // Attempt to use OSX certificates
                // Ideally we should return the SecTrustResult
                OSX509Certificates.SecTrustResult trustResult = OSX509Certificates.SecTrustResult.Deny;
                try {
                    trustResult = OSX509Certificates.TrustEvaluateSsl(certs, host);
                    // We could use the other values of trustResult to pass this extra information
                    // to the .NET 2 callback for values like SecTrustResult.Confirm
                    result = (trustResult == OSX509Certificates.SecTrustResult.Proceed ||
                              trustResult == OSX509Certificates.SecTrustResult.Unspecified);
                } catch {
                    // Ignore
                }

                if (result)
                {
                    // TrustEvaluateSsl was successful so there's no trust error
                    // IOW we discard our own chain (since we trust OSX one instead)
                    errors = 0;
                }
                else
                {
                    // callback and DefaultCertificatePolicy needs this since 'result' is not specified
                    status11 = (int)trustResult;
                    errors  |= SslPolicyErrors.RemoteCertificateChainErrors;
                }
            }


#if MONODROID && SECURITY_DEP
            if (!skipSystemValidators)
            {
                result = AndroidPlatform.TrustEvaluateSsl(certs, sender, leaf, chain, errors);
                if (result)
                {
                    // chain.Build() + GetErrorsFromChain() (above) will ALWAYS fail on
                    // Android (there are no mozroots or preinstalled root certificates),
                    // thus `errors` will ALWAYS have RemoteCertificateChainErrors.
                    // Android just verified the chain; clear RemoteCertificateChainErrors.
                    errors &= ~SslPolicyErrors.RemoteCertificateChainErrors;
                }
            }
#endif

            if (policy != null && (!(policy is DefaultCertificatePolicy) || certValidationCallback == null))
            {
                ServicePoint sp = null;
                if (request != null)
                {
                    sp = request.ServicePointNoLock;
                }
                if (status11 == 0 && errors != 0)
                {
                    status11 = GetStatusFromChain(chain);
                }

                // pre 2.0 callback
                result      = policy.CheckValidationResult(sp, leaf, request, status11);
                user_denied = !result && !(policy is DefaultCertificatePolicy);
            }
            // If there's a 2.0 callback, it takes precedence
            if (hasCallback)
            {
                if (callbackWrapper != null)
                {
                    result = callbackWrapper.Invoke(certValidationCallback, leaf, chain, (MonoSslPolicyErrors)errors);
                }
                else
                {
                    result = certValidationCallback.Invoke(sender, leaf, chain, errors);
                }
                user_denied = !result;
            }
            return(new ValidationResult(result, user_denied, status11, (MonoSslPolicyErrors)errors));
        }
            internal ValidationResult ValidateChain(Mono.Security.X509.X509CertificateCollection certs)
            {
                bool user_denied = false;

                if (certs == null || certs.Count == 0)
                {
                    return(null);
                }
                ICertificatePolicy certificatePolicy = ServicePointManager.CertificatePolicy;

                System.Net.Security.RemoteCertificateValidationCallback serverCertificateValidationCallback = ServicePointManager.ServerCertificateValidationCallback;
                System.Security.Cryptography.X509Certificates.X509Chain x509Chain = new System.Security.Cryptography.X509Certificates.X509Chain();
                x509Chain.ChainPolicy = new System.Security.Cryptography.X509Certificates.X509ChainPolicy();
                for (int i = 1; i < certs.Count; i++)
                {
                    System.Security.Cryptography.X509Certificates.X509Certificate2 certificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(certs[i].RawData);
                    x509Chain.ChainPolicy.ExtraStore.Add(certificate);
                }
                System.Security.Cryptography.X509Certificates.X509Certificate2 x509Certificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(certs[0].RawData);
                int num = 0;

                System.Net.Security.SslPolicyErrors sslPolicyErrors = System.Net.Security.SslPolicyErrors.None;
                try
                {
                    if (!x509Chain.Build(x509Certificate))
                    {
                        sslPolicyErrors |= ServicePointManager.ChainValidationHelper.GetErrorsFromChain(x509Chain);
                    }
                }
                catch (Exception arg)
                {
                    Console.Error.WriteLine("ERROR building certificate chain: {0}", arg);
                    Console.Error.WriteLine("Please, report this problem to the Mono team");
                    sslPolicyErrors |= System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors;
                }
                if (!ServicePointManager.ChainValidationHelper.CheckCertificateUsage(x509Certificate))
                {
                    sslPolicyErrors |= System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors;
                    num              = -2146762490;
                }
                if (!ServicePointManager.ChainValidationHelper.CheckServerIdentity(certs[0], this.Host))
                {
                    sslPolicyErrors |= System.Net.Security.SslPolicyErrors.RemoteCertificateNameMismatch;
                    num              = -2146762481;
                }
                bool flag = false;

                try
                {
                    OSX509Certificates.SecTrustResult secTrustResult = OSX509Certificates.TrustEvaluateSsl(certs);
                    flag = (secTrustResult == OSX509Certificates.SecTrustResult.Proceed || secTrustResult == OSX509Certificates.SecTrustResult.Unspecified);
                }
                catch
                {
                }
                if (flag)
                {
                    num             = 0;
                    sslPolicyErrors = System.Net.Security.SslPolicyErrors.None;
                }
                if (certificatePolicy != null && (!(certificatePolicy is DefaultCertificatePolicy) || serverCertificateValidationCallback == null))
                {
                    ServicePoint   srvPoint       = null;
                    HttpWebRequest httpWebRequest = this.sender as HttpWebRequest;
                    if (httpWebRequest != null)
                    {
                        srvPoint = httpWebRequest.ServicePoint;
                    }
                    if (num == 0 && sslPolicyErrors != System.Net.Security.SslPolicyErrors.None)
                    {
                        num = ServicePointManager.ChainValidationHelper.GetStatusFromChain(x509Chain);
                    }
                    flag        = certificatePolicy.CheckValidationResult(srvPoint, x509Certificate, httpWebRequest, num);
                    user_denied = (!flag && !(certificatePolicy is DefaultCertificatePolicy));
                }
                if (serverCertificateValidationCallback != null)
                {
                    flag        = serverCertificateValidationCallback(this.sender, x509Certificate, x509Chain, sslPolicyErrors);
                    user_denied = !flag;
                }
                return(new ValidationResult(flag, user_denied, num));
            }
Esempio n. 10
0
        ValidationResult ValidateChain(string host, XX509CertificateCollection certs, SslPolicyErrors errors)
        {
            // user_denied is true if the user callback is called and returns false
            bool user_denied = false;
            bool result      = false;

            var hasCallback = certValidationCallback != null || callbackWrapper != null;
            var anchors     = settings != null ? settings.TrustAnchors : null;

            var systemValidator = GetSystemCertificateValidator();

            X509Certificate leaf;

            if (certs == null || certs.Count == 0)
            {
                leaf = null;
            }
            else
            {
                leaf = certs [0];
            }

            if (tlsStream != null)
            {
                request.ServicePoint.SetServerCertificate(leaf);
            }

            if (leaf == null)
            {
                errors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                if (hasCallback)
                {
                    if (callbackWrapper != null)
                    {
                        result = callbackWrapper.Invoke(certValidationCallback, leaf, null, (MonoSslPolicyErrors)errors);
                    }
                    else
                    {
                        result = certValidationCallback.Invoke(sender, leaf, null, errors);
                    }
                    user_denied = !result;
                }
                return(new ValidationResult(result, user_denied, 0, (MonoSslPolicyErrors)errors));
            }

            bool needsChain;
            bool skipSystemValidators = false;

            if (!CertificateValidationHelper.SupportsX509Chain || is_mobile || is_macosx)
            {
                needsChain = false;
            }
            else if (settings != null)
            {
                skipSystemValidators = settings.SkipSystemValidators;
                needsChain           = !settings.SkipSystemValidators || settings.CallbackNeedsCertificateChain;
            }
            else
            {
                needsChain = true;
            }

            ICertificatePolicy policy = ServicePointManager.GetLegacyCertificatePolicy();

            int       status11 = 0;       // Error code passed to the obsolete ICertificatePolicy callback
            X509Chain chain    = null;

#if !MOBILE
            if (needsChain)
            {
                chain = systemValidator.ComputeX509Chain(certs, ref errors, ref status11);
            }
#endif

            systemValidator.CheckUsage(certs, host, ref errors, ref status11);

            if (!skipSystemValidators)
            {
                result = systemValidator.EvaluateSystem(certs, anchors, host, chain, ref errors, ref status11);
            }

            if (policy != null && (!(policy is DefaultCertificatePolicy) || certValidationCallback == null))
            {
                ServicePoint sp = null;
                if (request != null)
                {
                    sp = request.ServicePointNoLock;
                }
                if (status11 == 0 && errors != 0)
                {
                    // TRUST_E_FAIL
                    status11 = unchecked ((int)0x800B010B);
                }

                // pre 2.0 callback
                result      = policy.CheckValidationResult(sp, leaf, request, status11);
                user_denied = !result && !(policy is DefaultCertificatePolicy);
            }
            // If there's a 2.0 callback, it takes precedence
            if (hasCallback)
            {
                if (callbackWrapper != null)
                {
                    result = callbackWrapper.Invoke(certValidationCallback, leaf, chain, (MonoSslPolicyErrors)errors);
                }
                else
                {
                    result = certValidationCallback.Invoke(sender, leaf, chain, errors);
                }
                user_denied = !result;
            }
            return(new ValidationResult(result, user_denied, status11, (MonoSslPolicyErrors)errors));
        }