public static Func AuthorityPartOfChain()

in src/Elastic.Transport/Components/TransportClient/CertificateValidations.cs [38:87]


	public static Func<object, X509Certificate, X509Chain, SslPolicyErrors, bool> AuthorityPartOfChain(
		X509Certificate caCertificate, bool trustRoot = true, X509RevocationMode revocationMode = X509RevocationMode.NoCheck
	) =>
		(sender, cert, chain, errors) =>
			errors == SslPolicyErrors.None
			|| ValidIntermediateCa(caCertificate, cert, chain, trustRoot, revocationMode);

	/// <summary>
	/// Helper to create a certificate validation callback based on the certificate authority certificate that we used to
	/// generate the nodes certificates with. This callback does NOT expect the CA to be part of the chain presented by the server.
	/// Including the root certificate in the chain increases the SSL handshake size.
	/// Elasticsearch's certgen by default does not include the CA in the certificate chain.
	/// </summary>
	/// <param name="caCertificate">The ca certificate used to generate the nodes certificate </param>
	/// <param name="trustRoot">
	/// Custom CA are never trusted by default unless they are in the machines trusted store, set this to true
	/// if you've added the CA to the machines trusted store. In which case UntrustedRoot should not be accepted.
	/// </param>
	/// <param name="revocationMode">By default we do not check revocation, it is however recommended to check this (either offline or online).</param>
	public static Func<object, X509Certificate, X509Chain, SslPolicyErrors, bool> AuthorityIsRoot(
		X509Certificate caCertificate, bool trustRoot = true, X509RevocationMode revocationMode = X509RevocationMode.NoCheck
	) =>
		(sender, cert, chain, errors) =>
			errors == SslPolicyErrors.None
			|| ValidRootCa(caCertificate, cert, trustRoot, revocationMode);

	private static bool ValidRootCa(X509Certificate caCertificate, X509Certificate certificate, bool trustRoot,
		X509RevocationMode revocationMode
	)
	{
		var ca = new X509Certificate2(caCertificate);
		var privateChain = new X509Chain { ChainPolicy = { RevocationMode = revocationMode } };
		privateChain.ChainPolicy.ExtraStore.Add(ca);
		privateChain.Build(new X509Certificate2(certificate));

		//lets validate the our chain status
		foreach (var chainStatus in privateChain.ChainStatus)
		{
			//custom CA's that are not in the machine trusted store will always have this status
			//by setting trustRoot = true (default) we skip this error
			if (chainStatus.Status == X509ChainStatusFlags.UntrustedRoot && trustRoot) continue;

			//trustRoot is false so we expected our CA to be in the machines trusted store
			if (chainStatus.Status == X509ChainStatusFlags.UntrustedRoot) return false;

			//otherwise if the chain has any error of any sort return false
			if (chainStatus.Status != X509ChainStatusFlags.NoError) return false;
		}
		return true;
	}