bool InvokeCallback(X509Certificate leaf, X509Chain chain, SslPolicyErrors errors) { object sender = null; if (request != null) { sender = request; } else if (owner != null && owner.TryGetTarget(out var sslStream)) { sender = sslStream; } return(certValidationCallback.Invoke(sender, leaf, chain, errors)); }
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)); }
internal static bool InvokeCallback(ServerCertValidationCallback callback, object sender, X509Certificate certificate, X509Chain chain, MonoSslPolicyErrors sslPolicyErrors) { return(callback.Invoke(sender, certificate, chain, (SslPolicyErrors)sslPolicyErrors)); }
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)); }
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)); }
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)); }