public virtual X509Chain ComputeX509Chain (XX509CertificateCollection certs, ref SslPolicyErrors errors, ref int status11)
		{
#if MOBILE
			return null;
#else
			if (is_macosx)
				return null;

			var chain = new X509Chain ();
			chain.ChainPolicy = new X509ChainPolicy ();

			chain.ChainPolicy.RevocationMode = revocation_mode;

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

			var leaf = (X509Certificate2)certs [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;
			}

			status11 = GetStatusFromChain (chain);

			return chain;
#endif
		}
Exemplo n.º 2
0
		internal static SSPIInterface Create (string hostname, bool serverMode, SchProtocols protocolFlags, X509Certificate serverCertificate, XX509CertificateCollection clientCertificates,
		                                           bool remoteCertRequired, bool checkCertName, bool checkCertRevocationStatus, EncryptionPolicy encryptionPolicy,
		                                           LocalCertSelectionCallback certSelectionDelegate, RemoteCertValidationCallback remoteValidationCallback, SSPIConfiguration userConfig)
		{
			if (userConfig.Settings != null && remoteValidationCallback != null)
				throw new InvalidOperationException ();
			var context = userConfig.Provider.CreateTlsContext (
				hostname, serverMode, (TlsProtocols)protocolFlags, serverCertificate, clientCertificates,
				remoteCertRequired, checkCertName, checkCertRevocationStatus,
				(MonoEncryptionPolicy)encryptionPolicy, userConfig.Settings);
			return new SSPIInterface (context, userConfig.EventSink);
		}
Exemplo n.º 3
0
		public static X509Chain CreateX509Chain (XX509CertificateCollection certs)
		{
			var chain = new X509Chain ();
			chain.ChainPolicy = new X509ChainPolicy ();

#if !MOBILE
			chain.ChainPolicy.RevocationMode = revocation_mode;
#endif

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

			return chain;
		}
Exemplo n.º 4
0
/*
		AsymmetricAlgorithm GetPrivateKey (X509Certificate cert, string targetHost)
		{
			// FIXME: what can I do for non-X509Certificate2 ?
			X509Certificate2 cert2 = cert as X509Certificate2;
			return cert2 != null ? cert2.PrivateKey : null;
		}
*/
		X509Certificate OnCertificateSelection (X509CertificateCollection clientCerts, X509Certificate serverCert, string targetHost, X509CertificateCollection serverRequestedCerts)
		{
			string [] acceptableIssuers = new string [serverRequestedCerts != null ? serverRequestedCerts.Count : 0];
			for (int i = 0; i < acceptableIssuers.Length; i++)
				acceptableIssuers [i] = serverRequestedCerts [i].GetIssuerName ();
			return selection_callback (this, targetHost, clientCerts, serverCert, acceptableIssuers);
		}
Exemplo n.º 5
0
		public virtual void AuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
		{
			EndAuthenticateAsClient (BeginAuthenticateAsClient (
				targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation, null, null));
		}
Exemplo n.º 6
0
		public bool InvokeSystemValidator (string targetHost, bool serverMode, XX509CertificateCollection certificates, ref MonoSslPolicyErrors xerrors, ref int status11)
		{
			if (SystemCertificateValidator.NeedsChain (settings))
				throw new NotSupportedException ("Cannot use ICertificateValidator.InvokeSystemValidator() when the X509Chain is required.");

			X509Chain chain = null;
			var errors = (SslPolicyErrors)xerrors;
			var result = SystemCertificateValidator.Evaluate (settings, targetHost, certificates, ref chain, ref errors, ref status11);
			xerrors = (MonoSslPolicyErrors)errors;
			return result;
		}
Exemplo n.º 7
0
		public virtual IAsyncResult BeginAuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
		{
			if (IsAuthenticated)
				throw new InvalidOperationException ("This SslStream is already authenticated");

			SslClientStream s = new SslClientStream (InnerStream, targetHost, !LeaveInnerStreamOpen, GetMonoSslProtocol (enabledSslProtocols), clientCertificates);
			s.CheckCertRevocationStatus = checkCertificateRevocation;

			// Due to the Mono.Security internal, it cannot reuse
			// the delegated argument, as Mono.Security creates 
			// another instance of X509Certificate which lacks 
			// private key but is filled the private key via this
			// delegate.
			s.PrivateKeyCertSelectionDelegate = delegate (X509Certificate cert, string host) {
				string hash = cert.GetCertHashString ();
				// ... so, we cannot use the delegate argument.
				foreach (X509Certificate cc in clientCertificates) {
					if (cc.GetCertHashString () != hash)
						continue;
					X509Certificate2 cert2 = cc as X509Certificate2;
					cert2 = cert2 ?? new X509Certificate2 (cc);
					return cert2.PrivateKey;
				}
				return null;
			};

			// Even if validation_callback is null this allows us to verify requests where the user
			// does not provide a verification callback but attempts to authenticate with the website
			// as a client (see https://bugzilla.xamarin.com/show_bug.cgi?id=18962 for an example)
			s.ServerCertValidation2 += (mcerts) => {
				X509CertificateCollection certs = null;
				if (mcerts != null) {
					certs = new X509CertificateCollection ();
					for (int i = 0; i < mcerts.Count; i++)
						certs.Add (new X509Certificate2 (mcerts [i].RawData));
				}
				return ((ChainValidationHelper)certificateValidator).ValidateChain (targetHost, certs);
			};
			s.ClientCertSelectionDelegate = OnCertificateSelection;

			ssl_stream = s;

			return BeginWrite (new byte [0], 0, 0, asyncCallback, asyncState);
		}
Exemplo n.º 8
0
        public virtual IAsyncResult BeginAuthenticateAsClient(string targetHost, X509CertificateCollection clientCertificates, SslProtocols sslProtocolType, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
        {
            if (IsAuthenticated)
            {
                throw new InvalidOperationException("This SslStream is already authenticated");
            }

            SslClientStream s = new SslClientStream(InnerStream, targetHost, !LeaveInnerStreamOpen, GetMonoSslProtocol(sslProtocolType), clientCertificates);

            s.CheckCertRevocationStatus = checkCertificateRevocation;

            // Due to the Mono.Security internal, it cannot reuse
            // the delegated argument, as Mono.Security creates
            // another instance of X509Certificate which lacks
            // private key but is filled the private key via this
            // delegate.
            s.PrivateKeyCertSelectionDelegate = delegate(X509Certificate cert, string host) {
                string hash = cert.GetCertHashString();
                // ... so, we cannot use the delegate argument.
                foreach (X509Certificate cc in clientCertificates)
                {
                    if (cc.GetCertHashString() != hash)
                    {
                        continue;
                    }
                    X509Certificate2 cert2 = cc as X509Certificate2;
                    cert2 = cert2 ?? new X509Certificate2(cc);
                    return(cert2.PrivateKey);
                }
                return(null);
            };

            if (validation_callback != null)
            {
                s.ServerCertValidationDelegate = delegate(X509Certificate cert, int [] certErrors) {
                    X509Chain        chain = new X509Chain();
                    X509Certificate2 x2    = (cert as X509Certificate2);
                    if (x2 == null)
                    {
                        x2 = new X509Certificate2(cert);
                    }

                    if (!ServicePointManager.CheckCertificateRevocationList)
                    {
                        chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
                    }

                    // SSL specific checks (done by Mono.Security.dll SSL/TLS implementation)
                    SslPolicyErrors errors = SslPolicyErrors.None;
                    foreach (int i in certErrors)
                    {
                        switch (i)
                        {
                        case -2146762490:                         // CERT_E_PURPOSE
                            errors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                            break;

                        case -2146762481:                         // CERT_E_CN_NO_MATCH
                            errors |= SslPolicyErrors.RemoteCertificateNameMismatch;
                            break;

                        default:
                            errors |= SslPolicyErrors.RemoteCertificateChainErrors;
                            break;
                        }
                    }

                    chain.Build(x2);

                    // non-SSL specific X509 checks (i.e. RFC3280 related checks)
                    foreach (X509ChainStatus status in chain.ChainStatus)
                    {
                        if ((status.Status & X509ChainStatusFlags.PartialChain) != 0)
                        {
                            errors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                        }
                        else
                        {
                            errors |= SslPolicyErrors.RemoteCertificateChainErrors;
                        }
                    }

                    return(validation_callback(this, cert, chain, errors));
                }
            }
            ;
            if (selection_callback != null)
            {
                s.ClientCertSelectionDelegate = OnCertificateSelection;
            }

            ssl_stream = s;

            return(BeginWrite(new byte [0], 0, 0, asyncCallback, asyncState));
        }
Exemplo n.º 9
0
		public ValidationResult ValidateChain (string host, XX509CertificateCollection certs)
		{
			try {
				var result = ValidateChain (host, true, certs, 0);
				if (tlsStream != null)
					tlsStream.CertificateValidationFailed = result == null || !result.Trusted || result.UserDenied;
				return result;
			} catch {
				if (tlsStream != null)
					tlsStream.CertificateValidationFailed = true;
				throw;
			}
		}
Exemplo n.º 10
0
        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));
        }
Exemplo n.º 11
0
        static SecTrustResult _TrustEvaluateSsl(XX509CertificateCollection certificates, XX509CertificateCollection anchors, string hostName)
        {
            int certCount   = certificates.Count;
            int anchorCount = anchors != null ? anchors.Count : 0;

            IntPtr []      cfDataPtrs       = new IntPtr [certCount];
            IntPtr []      secCerts         = new IntPtr [certCount];
            IntPtr []      cfDataAnchorPtrs = new IntPtr [anchorCount];
            IntPtr []      secCertAnchors   = new IntPtr [anchorCount];
            IntPtr         certArray        = IntPtr.Zero;
            IntPtr         anchorArray      = IntPtr.Zero;
            IntPtr         sslsecpolicy     = IntPtr.Zero;
            IntPtr         host             = IntPtr.Zero;
            IntPtr         sectrust         = IntPtr.Zero;
            SecTrustResult result           = SecTrustResult.Deny;

            try {
                for (int i = 0; i < certCount; i++)
                {
                    secCerts [i] = GetCertificate(certificates [i], out cfDataPtrs [i]);
                    if (secCerts [i] == IntPtr.Zero)
                    {
                        return(SecTrustResult.Deny);
                    }
                }

                for (int i = 0; i < anchorCount; i++)
                {
                    secCertAnchors [i] = GetCertificate(anchors [i], out cfDataAnchorPtrs [i]);
                    if (secCertAnchors [i] == IntPtr.Zero)
                    {
                        return(SecTrustResult.Deny);
                    }
                }

                certArray = FromIntPtrs(secCerts);

                host         = CFStringCreateWithCharacters(IntPtr.Zero, hostName, (IntPtr)hostName.Length);
                sslsecpolicy = SecPolicyCreateSSL(true, host);

                int code = SecTrustCreateWithCertificates(certArray, sslsecpolicy, out sectrust);
                if (code != 0)
                {
                    return(SecTrustResult.Deny);
                }

                if (anchorCount > 0)
                {
                    anchorArray = FromIntPtrs(secCertAnchors);
                    SecTrustSetAnchorCertificates(sectrust, anchorArray);
                }

                code = SecTrustEvaluate(sectrust, out result);
                return(result);
            } finally {
                for (int i = 0; i < certCount; i++)
                {
                    if (cfDataPtrs [i] != IntPtr.Zero)
                    {
                        CFRelease(cfDataPtrs [i]);
                    }
                }

                for (int i = 0; i < anchorCount; i++)
                {
                    if (cfDataAnchorPtrs [i] != IntPtr.Zero)
                    {
                        CFRelease(cfDataAnchorPtrs [i]);
                    }
                }

                if (certArray != IntPtr.Zero)
                {
                    CFRelease(certArray);
                }

                if (anchorArray != IntPtr.Zero)
                {
                    CFRelease(anchorArray);
                }

                for (int i = 0; i < certCount; i++)
                {
                    if (secCerts [i] != IntPtr.Zero)
                    {
                        CFRelease(secCerts [i]);
                    }
                }

                for (int i = 0; i < anchorCount; i++)
                {
                    if (secCertAnchors [i] != IntPtr.Zero)
                    {
                        CFRelease(secCertAnchors [i]);
                    }
                }

                if (sslsecpolicy != IntPtr.Zero)
                {
                    CFRelease(sslsecpolicy);
                }
                if (host != IntPtr.Zero)
                {
                    CFRelease(host);
                }
                if (sectrust != IntPtr.Zero)
                {
                    CFRelease(sectrust);
                }
            }
        }
Exemplo n.º 12
0
/*
 *              AsymmetricAlgorithm GetPrivateKey (X509Certificate cert, string targetHost)
 *              {
 *                      // FIXME: what can I do for non-X509Certificate2 ?
 *                      X509Certificate2 cert2 = cert as X509Certificate2;
 *                      return cert2 != null ? cert2.PrivateKey : null;
 *              }
 */
        X509Certificate OnCertificateSelection(X509CertificateCollection clientCerts, X509Certificate serverCert, string targetHost, X509CertificateCollection serverRequestedCerts)
        {
            string [] acceptableIssuers = new string [serverRequestedCerts != null ? serverRequestedCerts.Count : 0];
            for (int i = 0; i < acceptableIssuers.Length; i++)
            {
                acceptableIssuers [i] = serverRequestedCerts [i].GetIssuerName();
            }
            X509Certificate clientCertificate;

            certificateValidator.SelectClientCertificate(targetHost, clientCerts, serverCert, acceptableIssuers, out clientCertificate);
            return(clientCertificate);
        }
Exemplo n.º 13
0
 public virtual void AuthenticateAsClient(string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
 {
     EndAuthenticateAsClient(BeginAuthenticateAsClient(
                                 targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation, null, null));
 }
Exemplo n.º 14
0
 public void AuthenticateAsClient(string targetHost, XX509CertificateCollection clientCertificates, XSslProtocols enabledSslProtocols, bool checkCertificateRevocation)
 {
     Impl.AuthenticateAsClient(targetHost, clientCertificates, (SslProtocols)enabledSslProtocols, checkCertificateRevocation);
 }
Exemplo n.º 15
0
 public Task AuthenticateAsClientAsync(string targetHost, XX509CertificateCollection clientCertificates, XSslProtocols enabledSslProtocols, bool checkCertificateRevocation)
 {
     return(Impl.AuthenticateAsClientAsync(targetHost, clientCertificates, (SslProtocols)enabledSslProtocols, checkCertificateRevocation));
 }
Exemplo n.º 16
0
 public IAsyncResult BeginAuthenticateAsClient(string targetHost, XX509CertificateCollection clientCertificates, XSslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
 {
     return(Impl.BeginAuthenticateAsClient(targetHost, clientCertificates, (SslProtocols)enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState));
 }
Exemplo n.º 17
0
		internal X509Certificate SelectClientCertificate (string targetHost, XX509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] acceptableIssuers)
		{
			X509Certificate clientCertificate;
			if (localCertificates == null || localCertificates.Count == 0)
				clientCertificate = null;
			else
				clientCertificate = localCertificates [0];
			return clientCertificate;
		}
Exemplo n.º 18
0
		static X509Certificate DefaultSelectionCallback (string targetHost, XX509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] acceptableIssuers)
		{
			X509Certificate clientCertificate;
			if (localCertificates == null || localCertificates.Count == 0)
				clientCertificate = null;
			else
				clientCertificate = localCertificates [0];
			return clientCertificate;
		}
Exemplo n.º 19
0
		// [HostProtection (ExternalThreading=true)]
		public virtual IAsyncResult BeginAuthenticateAsClient (string targetHost, XX509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
		{
			return Impl.BeginAuthenticateAsClient (targetHost, (XX509CertificateCollection)(object)clientCertificates, (XSslProtocols)enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState);
		}
Exemplo n.º 20
0
		internal bool ValidateClientCertificate (X509Certificate certificate, MonoSslPolicyErrors errors)
		{
			var certs = new XX509CertificateCollection ();
			certs.Add (new X509Certificate2 (certificate.GetRawCertData ()));

			var result = ValidateChain (string.Empty, false, certs, (SslPolicyErrors)errors);
			if (result == null)
				return false;

			return result.Trusted && !result.UserDenied;
		}
Exemplo n.º 21
0
		public bool InvokeSystemValidator (string targetHost, bool serverMode, XX509CertificateCollection certificates, XX509Chain xchain, ref MonoSslPolicyErrors xerrors, ref int status11)
		{
			X509Chain chain = (X509Chain)(object)xchain;
			var errors = (SslPolicyErrors)xerrors;
			var result = SystemCertificateValidator.Evaluate (settings, targetHost, certificates, chain, ref errors, ref status11);
			xerrors = (MonoSslPolicyErrors)errors;
			return result;
		}
Exemplo n.º 22
0
/*
 *              AsymmetricAlgorithm GetPrivateKey (X509Certificate cert, string targetHost)
 *              {
 *                      // FIXME: what can I do for non-X509Certificate2 ?
 *                      X509Certificate2 cert2 = cert as X509Certificate2;
 *                      return cert2 != null ? cert2.PrivateKey : null;
 *              }
 */
        X509Certificate OnCertificateSelection(X509CertificateCollection clientCerts, X509Certificate serverCert, string targetHost, X509CertificateCollection serverRequestedCerts)
        {
            string [] acceptableIssuers = new string [serverRequestedCerts != null ? serverRequestedCerts.Count : 0];
            for (int i = 0; i < acceptableIssuers.Length; i++)
            {
                acceptableIssuers [i] = serverRequestedCerts [i].GetIssuerName();
            }
            return(selection_callback(this, targetHost, clientCerts, serverCert, acceptableIssuers));
        }
Exemplo n.º 23
0
		public X509Certificate SelectClientCertificate (
			string targetHost, XX509CertificateCollection localCertificates, X509Certificate remoteCertificate,
			string[] acceptableIssuers)
		{
			if (certSelectionCallback == null)
				return null;
			return certSelectionCallback (targetHost, localCertificates, remoteCertificate, acceptableIssuers);
		}
Exemplo n.º 24
0
		public static bool Evaluate (
			MonoTlsSettings settings, string host, XX509CertificateCollection certs,
			X509Chain chain, ref SslPolicyErrors errors, ref int status11)
		{
			if (!CheckUsage (certs, host, ref errors, ref status11))
				return false;

			if (settings != null && settings.SkipSystemValidators)
				return false;

			var anchors = settings != null ? settings.TrustAnchors : null;
			return EvaluateSystem (certs, anchors, host, chain, ref errors, ref status11);
		}
Exemplo n.º 25
0
		public ValidationResult ValidateClientCertificate (XX509CertificateCollection certs)
		{
			return ValidateChain (string.Empty, false, certs, 0);
		}
Exemplo n.º 26
0
		public static bool BuildX509Chain (XX509CertificateCollection certs, X509Chain chain, ref SslPolicyErrors errors, ref int status11)
		{
#if MOBILE
			return true;
#else
			if (is_macosx)
				return true;

			var leaf = (X509Certificate2)certs [0];

			bool ok;
			try {
				ok = chain.Build (leaf);
				if (!ok)
					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;
				ok = false;
			}

			try {
				status11 = GetStatusFromChain (chain);
			} catch {
				status11 = -2146762485; // TRUST_E_FAIL - generic
			}

			return ok;
#endif
		}
Exemplo n.º 27
0
		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;

			if (provider != null && provider.HasCustomSystemCertificateValidator) {
				if (SystemCertificateValidator.NeedsChain (settings))
					throw new NotSupportedException ("Cannot use MonoTlsProvider.InvokeSystemCertificateValidator() when the X509Chain is required.");
				var xerrors = (MonoSslPolicyErrors)errors;
				result = provider.InvokeSystemCertificateValidator (this, host, server, certs, ref xerrors, ref status11);
				errors = (SslPolicyErrors)xerrors;
			} else {
				result = SystemCertificateValidator.Evaluate (settings, host, certs, ref 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);
		}
Exemplo n.º 28
0
		public MSI.IMonoTlsContext CreateTlsContext (
			string hostname, bool serverMode, MSI.TlsProtocols protocolFlags,
			X509Certificate serverCertificate, XX509CertificateCollection clientCertificates,
			bool remoteCertRequired, bool checkCertName, bool checkCertRevocationStatus,
			MSI.MonoEncryptionPolicy encryptionPolicy, MSI.MonoTlsSettings settings)
		{
			return provider.CreateTlsContext (
				hostname, serverMode, protocolFlags,
				serverCertificate, (XX509CertificateCollection)(object)clientCertificates,
				remoteCertRequired, (MSI.MonoEncryptionPolicy)encryptionPolicy,
				settings);
		}
Exemplo n.º 29
0
/*
		AsymmetricAlgorithm GetPrivateKey (X509Certificate cert, string targetHost)
		{
			// FIXME: what can I do for non-X509Certificate2 ?
			X509Certificate2 cert2 = cert as X509Certificate2;
			return cert2 != null ? cert2.PrivateKey : null;
		}
*/
		X509Certificate OnCertificateSelection (X509CertificateCollection clientCerts, X509Certificate serverCert, string targetHost, X509CertificateCollection serverRequestedCerts)
		{
			string [] acceptableIssuers = new string [serverRequestedCerts != null ? serverRequestedCerts.Count : 0];
			for (int i = 0; i < acceptableIssuers.Length; i++)
				acceptableIssuers [i] = serverRequestedCerts [i].GetIssuerName ();
			X509Certificate clientCertificate;
			certificateValidator.SelectClientCertificate (targetHost, clientCerts, serverCert, acceptableIssuers, out clientCertificate);
			return clientCertificate;
		}
Exemplo n.º 30
0
		public static SecTrustResult TrustEvaluateSsl (XX509CertificateCollection certificates, XX509CertificateCollection anchors, string host)
		{
			if (certificates == null)
				return SecTrustResult.Deny;

			try {
				return _TrustEvaluateSsl (certificates, anchors, host);
			} catch {
				return SecTrustResult.Deny;
			}
		}
Exemplo n.º 31
0
		public override void AuthenticateAsClient (string targetHost, XX509CertificateCollection clientCertificates, XSslProtocols enabledSslProtocols, bool checkCertificateRevocation)
		{
			Impl.AuthenticateAsClient (targetHost, clientCertificates, (XSslProtocols)enabledSslProtocols, checkCertificateRevocation);
		}
Exemplo n.º 32
0
		static SecTrustResult _TrustEvaluateSsl (XX509CertificateCollection certificates, XX509CertificateCollection anchors, string hostName)
		{
			int certCount = certificates.Count;
			int anchorCount = anchors != null ? anchors.Count : 0;
			IntPtr [] cfDataPtrs = new IntPtr [certCount];
			IntPtr [] secCerts = new IntPtr [certCount];
			IntPtr [] cfDataAnchorPtrs = new IntPtr [anchorCount];
			IntPtr [] secCertAnchors = new IntPtr [anchorCount];
			IntPtr certArray = IntPtr.Zero;
			IntPtr anchorArray = IntPtr.Zero;
			IntPtr sslsecpolicy = IntPtr.Zero;
			IntPtr host = IntPtr.Zero;
			IntPtr sectrust = IntPtr.Zero;
			SecTrustResult result = SecTrustResult.Deny;

			try {
				for (int i = 0; i < certCount; i++)
					cfDataPtrs [i] = MakeCFData (certificates [i].GetRawCertData ());
				for (int i = 0; i < anchorCount; i++)
					cfDataAnchorPtrs [i] = MakeCFData (anchors [i].GetRawCertData ());
				
				for (int i = 0; i < certCount; i++){
					secCerts [i] = SecCertificateCreateWithData (IntPtr.Zero, cfDataPtrs [i]);
					if (secCerts [i] == IntPtr.Zero)
						return SecTrustResult.Deny;
				}

				for (int i = 0; i < anchorCount; i++) {
					secCertAnchors [i] = SecCertificateCreateWithData (IntPtr.Zero, cfDataAnchorPtrs [i]);
					if (secCertAnchors [i] == IntPtr.Zero)
						return SecTrustResult.Deny;
				}

				certArray = FromIntPtrs (secCerts);

				host = CFStringCreateWithCharacters (IntPtr.Zero, hostName, (IntPtr) hostName.Length);
				sslsecpolicy = SecPolicyCreateSSL (true, host);

				int code = SecTrustCreateWithCertificates (certArray, sslsecpolicy, out sectrust);
				if (code != 0)
					return SecTrustResult.Deny;

				if (anchorCount > 0) {
					anchorArray = FromIntPtrs (secCertAnchors);
					SecTrustSetAnchorCertificates (sectrust, anchorArray);
				}

				code = SecTrustEvaluate (sectrust, out result);
				return result;
			} finally {
				for (int i = 0; i < certCount; i++)
					if (cfDataPtrs [i] != IntPtr.Zero)
						CFRelease (cfDataPtrs [i]);

				for (int i = 0; i < anchorCount; i++)
					if (cfDataAnchorPtrs [i] != IntPtr.Zero)
						CFRelease (cfDataAnchorPtrs [i]);

				if (certArray != IntPtr.Zero)
					CFRelease (certArray);

				if (anchorArray != IntPtr.Zero)
					CFRelease (anchorArray);
				
				for (int i = 0; i < certCount; i++)
					if (secCerts [i] != IntPtr.Zero)
						CFRelease (secCerts [i]);

				for (int i = 0; i < anchorCount; i++)
					if (secCertAnchors [i] != IntPtr.Zero)
						CFRelease (secCertAnchors [i]);

				if (sslsecpolicy != IntPtr.Zero)
					CFRelease (sslsecpolicy);
				if (host != IntPtr.Zero)
					CFRelease (host);
				if (sectrust != IntPtr.Zero)
					CFRelease (sectrust);
			}
		}
Exemplo n.º 33
0
		public virtual IAsyncResult BeginAuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
		{
			if (IsAuthenticated)
				throw new InvalidOperationException ("This SslStream is already authenticated");

			SslClientStream s = new SslClientStream (InnerStream, targetHost, !LeaveInnerStreamOpen, GetMonoSslProtocol (enabledSslProtocols), clientCertificates);
			s.CheckCertRevocationStatus = checkCertificateRevocation;

			// Due to the Mono.Security internal, it cannot reuse
			// the delegated argument, as Mono.Security creates 
			// another instance of X509Certificate which lacks 
			// private key but is filled the private key via this
			// delegate.
			s.PrivateKeyCertSelectionDelegate = delegate (X509Certificate cert, string host) {
				string hash = cert.GetCertHashString ();
				// ... so, we cannot use the delegate argument.
				foreach (X509Certificate cc in clientCertificates) {
					if (cc.GetCertHashString () != hash)
						continue;
					X509Certificate2 cert2 = cc as X509Certificate2;
					cert2 = cert2 ?? new X509Certificate2 (cc);
					return cert2.PrivateKey;
				}
				return null;
			};

			if (validation_callback != null)
				s.ServerCertValidationDelegate = delegate (X509Certificate cert, int [] certErrors) {
					X509Chain chain = new X509Chain ();
					X509Certificate2 x2 = (cert as X509Certificate2);
					if (x2 == null)
						x2 = new X509Certificate2 (cert);

					if (!ServicePointManager.CheckCertificateRevocationList)
						chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;

					// SSL specific checks (done by Mono.Security.dll SSL/TLS implementation) 
					SslPolicyErrors errors = SslPolicyErrors.None;
					foreach (int i in certErrors) {
						switch (i) {
						case -2146762490: // CERT_E_PURPOSE
							errors |= SslPolicyErrors.RemoteCertificateNotAvailable;
							break;
						case -2146762481: // CERT_E_CN_NO_MATCH
							errors |= SslPolicyErrors.RemoteCertificateNameMismatch;
							break;
						default:
							errors |= SslPolicyErrors.RemoteCertificateChainErrors;
							break;
						}
					}

					chain.Build (x2);

					// non-SSL specific X509 checks (i.e. RFC3280 related checks)
					foreach (X509ChainStatus status in chain.ChainStatus) {
						if (status.Status == X509ChainStatusFlags.NoError)
							continue;
						if ((status.Status & X509ChainStatusFlags.PartialChain) != 0)
							errors |= SslPolicyErrors.RemoteCertificateNotAvailable;
						else
							errors |= SslPolicyErrors.RemoteCertificateChainErrors;
					}

					return validation_callback (this, cert, chain, errors);
				};
			if (selection_callback != null)
				s.ClientCertSelectionDelegate = OnCertificateSelection;

			ssl_stream = s;

			return BeginWrite (new byte [0], 0, 0, asyncCallback, asyncState);
		}
Exemplo n.º 34
0
		static X509Certificate2Collection Convert (XX509CertificateCollection certificates)
		{
			var certs2 = (object)certificates as X509Certificate2Collection;
			if (certs2 != null || certificates == null)
				return certs2;

			certs2 = new X509Certificate2Collection ();
			for (int i = 0; i < certificates.Count; i++)
				certs2.Add ((X509Certificate2)certificates [i]);
			return certs2;
		}
Exemplo n.º 35
0
		public virtual Task AuthenticateAsClientAsync (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
		{
			var t = Tuple.Create (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation, this);

			return Task.Factory.FromAsync ((callback, state) => {
				var d = (Tuple<string, X509CertificateCollection, SslProtocols, bool, SslStream>) state;
				return d.Item5.BeginAuthenticateAsClient (d.Item1, d.Item2, d.Item3, d.Item4, callback, null);
			}, EndAuthenticateAsClient, t);
		}
Exemplo n.º 36
0
		public ValidationResult ValidateClientCertificate (XX509CertificateCollection certs)
		{
			var certs2 = Convert (certs);
			return ValidateChain (null, certs2, 0);
		}
Exemplo n.º 37
0
		public virtual void AuthenticateAsClient (string targetHost, XX509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
		{
			Impl.AuthenticateAsClient (targetHost, (XX509CertificateCollection)(object)clientCertificates, (XSslProtocols)enabledSslProtocols, checkCertificateRevocation);
		}
Exemplo n.º 38
0
		public bool SelectClientCertificate (
			string targetHost, XX509CertificateCollection localCertificates, X509Certificate remoteCertificate,
			string[] acceptableIssuers, out X509Certificate clientCertificate)
		{
			if (certSelectionCallback == null) {
				clientCertificate = null;
				return false;
			}
			clientCertificate = certSelectionCallback (targetHost, localCertificates, remoteCertificate, acceptableIssuers);
			return true;
		}
Exemplo n.º 39
0
		public virtual Task AuthenticateAsClientAsync (string targetHost, XX509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
		{
			return Impl.AuthenticateAsClientAsync (targetHost, clientCertificates, (XSslProtocols)enabledSslProtocols, checkCertificateRevocation);
		}
Exemplo n.º 40
0
        public static SecTrustResult TrustEvaluateSsl(XX509CertificateCollection certificates, XX509CertificateCollection anchors, string host)
        {
            if (certificates == null)
            {
                return(SecTrustResult.Deny);
            }

            try {
                return(_TrustEvaluateSsl(certificates, anchors, host));
            } catch {
                return(SecTrustResult.Deny);
            }
        }