System.Net.ServicePointManager.ChainValidationHelper.ValidateChain C# (CSharp) Method

ValidateChain() private method

private ValidateChain ( Mono certs ) : ValidationResult
certs Mono
return Mono.Security.Protocol.Tls.ValidationResult
			internal ValidationResult ValidateChain (Mono.Security.X509.X509CertificateCollection certs)
			{
				// user_denied is true if the user callback is called and returns false
				bool user_denied = false;
				if (certs == null || certs.Count == 0)
					return null;

				ICertificatePolicy policy = ServicePointManager.CertificatePolicy;
				RemoteCertificateValidationCallback cb = ServicePointManager.ServerCertificateValidationCallback;

				X509Chain chain = new X509Chain ();
				chain.ChainPolicy = new X509ChainPolicy ();
				chain.ChainPolicy.RevocationMode = revocation_mode;
				for (int i = 1; i < certs.Count; i++) {
					X509Certificate2 c2 = new X509Certificate2 (certs [i].RawData);
					chain.ChainPolicy.ExtraStore.Add (c2);
				}

				X509Certificate2 leaf = new X509Certificate2 (certs [0].RawData);
				int status11 = 0; // Error code passed to the obsolete ICertificatePolicy callback
				SslPolicyErrors errors = 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;
				}

				if (!CheckCertificateUsage (leaf)) {
					errors |= SslPolicyErrors.RemoteCertificateChainErrors;
					status11 = -2146762490; //CERT_E_PURPOSE 0x800B0106
				}

				if (!CheckServerIdentity (certs [0], Host)) {
					errors |= SslPolicyErrors.RemoteCertificateNameMismatch;
					status11 = -2146762481; // CERT_E_CN_NO_MATCH 0x800B010F
				}

				bool result = false;
				// No certificate root found means no mozroots or monotouch
#if !MONOTOUCH
				if (is_macosx) {
#endif
					// Attempt to use OSX certificates
					// Ideally we should return the SecTrustResult
					MSX.OSX509Certificates.SecTrustResult trustResult;
					try {
						trustResult = MSX.OSX509Certificates.TrustEvaluateSsl (certs);
						// 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 == MSX.OSX509Certificates.SecTrustResult.Proceed ||
								  trustResult == MSX.OSX509Certificates.SecTrustResult.Unspecified);

					} catch {
						// Ignore
					}
					// Clear error status if the OS told us to trust the certificate
					if (result) {
						status11 = 0;
						errors = 0;
					}
#if !MONOTOUCH
				}
#endif

				if (policy != null && (!(policy is DefaultCertificatePolicy) || cb == null)) {
					ServicePoint sp = null;
					HttpWebRequest req = sender as HttpWebRequest;
					if (req != null)
						sp = req.ServicePoint;
					if (status11 == 0 && errors != 0)
						status11 = GetStatusFromChain (chain);

					// pre 2.0 callback
					result = policy.CheckValidationResult (sp, leaf, req, status11);
					user_denied = !result && !(policy is DefaultCertificatePolicy);
				}
				// If there's a 2.0 callback, it takes precedence
				if (cb != null) {
					result = cb (sender, leaf, chain, errors);
					user_denied = !result;
				}
				return new ValidationResult (result, user_denied, status11);
			}