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); }
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); } }