Example #1
0
        public static bool InvokeSystemCertificateValidator(
            ICertificateValidator2 validator, string targetHost, bool serverMode,
            X509CertificateCollection certificates,
            ref MonoSslPolicyErrors errors, ref int status11)
        {
            if (certificates == null)
            {
                errors |= MonoSslPolicyErrors.RemoteCertificateNotAvailable;
                return(false);
            }

            if (!string.IsNullOrEmpty(targetHost))
            {
                var pos = targetHost.IndexOf(':');
                if (pos > 0)
                {
                    targetHost = targetHost.Substring(0, pos);
                }
            }

            var policy = SecPolicy.CreateSslPolicy(!serverMode, targetHost);
            var trust  = new SecTrust(certificates, policy);

            if (validator.Settings.TrustAnchors != null)
            {
                var status = trust.SetAnchorCertificates(validator.Settings.TrustAnchors);
                if (status != SecStatusCode.Success)
                {
                    throw new InvalidOperationException(status.ToString());
                }
                trust.SetAnchorCertificatesOnly(false);
            }

            if (validator.Settings.CertificateValidationTime != null)
            {
                var status = trust.SetVerifyDate(validator.Settings.CertificateValidationTime.Value);
                if (status != SecStatusCode.Success)
                {
                    throw new InvalidOperationException(status.ToString());
                }
            }

            var result = trust.Evaluate();

            if (result == SecTrustResult.Unspecified)
            {
                return(true);
            }

            errors |= MonoSslPolicyErrors.RemoteCertificateChainErrors;
            return(false);
        }
Example #2
0
        void EvaluateTrust()
        {
            InitializeSession();

            /*
             * We're using .NET's SslStream semantics here.
             *
             * A server must always provide a valid certificate.
             *
             * However, in server mode, "ask for client certificate" means that
             * we ask the client to provide a certificate, then invoke the client
             * certificate validator - passing 'null' if the client didn't provide
             * any.
             *
             */

            bool     ok;
            SecTrust trust = null;
            X509CertificateCollection certificates = null;

            try {
                trust = GetPeerTrust(!IsServer);

                if (trust == null || trust.Count == 0)
                {
                    remoteCertificate = null;
                    if (!IsServer)
                    {
                        throw new TlsException(AlertDescription.CertificateUnknown);
                    }
                    certificates = null;
                }
                else
                {
                    if (trust.Count > 1)
                    {
                        Debug("WARNING: Got multiple certificates in SecTrust!");
                    }

                    certificates = new X509CertificateCollection();
                    for (int i = 0; i < trust.Count; i++)
                    {
                        certificates.Add(trust.GetCertificate(i));
                    }

                    remoteCertificate = new X509Certificate(certificates [0]);
                    Debug("Got peer trust: {0}", remoteCertificate);
                }

                ok = ValidateCertificate(certificates);
            } catch (Exception ex) {
                Debug("Certificate validation failed: {0}", ex);
                throw new TlsException(AlertDescription.CertificateUnknown, "Certificate validation threw exception.");
            } finally {
                if (trust != null)
                {
                    trust.Dispose();
                }
                if (certificates != null)
                {
                    for (int i = 0; i < certificates.Count; i++)
                    {
                        certificates [i].Dispose();
                    }
                }
            }

            if (!ok)
            {
                throw new TlsException(AlertDescription.CertificateUnknown);
            }
        }