protected override void Clear ()
		{
			if (context != null) {
				context.Clear ();
				context = null;
			}
		}
		internal static bool CheckClientCertificate (TlsContext context, MX.X509CertificateCollection certificates)
		{
			if (certificates == null || certificates.Count < 1) {
				if (!context.SettingsProvider.AskForClientCertificate)
					return false;
				if (context.SettingsProvider.RequireClientCertificate)
					throw new TlsException (AlertDescription.CertificateUnknown);
			}

			if (context.SettingsProvider.HasClientCertificateParameters) {
				var certParams = context.SettingsProvider.ClientCertificateParameters;
				if (certParams.CertificateAuthorities.Count > 0) {
					if (!certParams.CertificateAuthorities.Contains (certificates [0].IssuerName))
						throw new TlsException (AlertDescription.BadCertificate);
				}
			}

			var helper = context.Configuration.CertificateValidator;
			if (helper == null)
				helper = CertificateValidationHelper.CreateDefaultValidator (context.Configuration.TlsSettings);

			var result = helper.ValidateClientCertificate (certificates);
			if (result != null && result.Trusted && !result.UserDenied)
				return true;

			throw new TlsException (AlertDescription.CertificateUnknown);
		}
		internal static bool VerifyServerCertificate (TlsContext context, MX.X509Certificate certificate, ExchangeAlgorithmType algorithm)
		{
			if (context.NegotiatedProtocol == TlsProtocolCode.Tls12 && certificate.Version < 3)
				throw new TlsException (AlertDescription.UnsupportedCertificate, "X.509v3 server certificate required");

			if (certificate.KeyAlgorithm != null && !certificate.KeyAlgorithm.Equals (OidKeyAlgorithmRsa))
				return false;
			if (certificate.SignatureAlgorithm != null && !VerifySignatureAlgorithm (certificate.SignatureAlgorithm))
				return false;

			switch (algorithm) {
			case ExchangeAlgorithmType.Rsa:
				return VerifyKeyUsage (certificate, KeyUsages.keyEncipherment, OidServerAuth);

			case ExchangeAlgorithmType.Dhe:
			case ExchangeAlgorithmType.EcDhe:
				return VerifyKeyUsage (certificate, KeyUsages.digitalSignature, OidServerAuth);

			default:
				throw new TlsException (AlertDescription.InternalError);
			}
		}
		internal static void CheckClientCertificate (TlsContext context, MX.X509CertificateCollection certificates)
		{
			if (context.SettingsProvider.HasClientCertificateParameters) {
				var certParams = context.SettingsProvider.ClientCertificateParameters;
				if (certParams.CertificateAuthorities.Count > 0) {
					if (!certParams.CertificateAuthorities.Contains (certificates [0].IssuerName))
						throw new TlsException (AlertDescription.BadCertificate);
				}
			}

			var helper = CertificateValidationHelper.GetValidator (context.Configuration.TlsSettings);

			X509Certificate2Collection scerts = null;
			if (certificates != null) {
				scerts = new X509Certificate2Collection ();
				for (int i = 0; i < certificates.Count; i++)
					scerts.Add (new X509Certificate2 (certificates [i].RawData));
			}

			var result = helper.ValidateClientCertificate (scerts);
			if (result == null || !result.Trusted || result.UserDenied)
				throw new TlsException (AlertDescription.CertificateUnknown);
		}
		public void Initialize (MSI.IMonoTlsEventSink eventSink)
		{
			if (context != null)
				throw new InvalidOperationException ();
			context = new TlsContext (config, serverMode, eventSink);
		}
		public void Initialize ()
		{
			if (context != null)
				throw new InvalidOperationException ();
			context = new TlsContext (config, serverMode);
		}
			public ServerConnectionHandler (TlsContext context, bool renegotiating)
				: base (context, renegotiating)
			{
			}
			public ServerHelloHandler (TlsContext context)
				: base (context)
			{
			}