in src/Elastic.Transport/Components/TransportClient/CertificateValidations.cs [89:128]
private static bool ValidIntermediateCa(X509Certificate caCertificate, X509Certificate certificate, X509Chain chain, 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));
//Assert our chain has the same number of elements as the certifcate presented by the server
if (chain.ChainElements.Count != privateChain.ChainElements.Count) return false;
//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;
}
var found = false;
//We are going to walk both chains and make sure the thumbprints align
//while making sure one of the chains certificates presented by the server has our expected CA thumbprint
for (var i = 0; i < chain.ChainElements.Count; i++)
{
var c = chain.ChainElements[i].Certificate.Thumbprint;
var cPrivate = privateChain.ChainElements[i].Certificate.Thumbprint;
if (!found && c == ca.Thumbprint) found = true;
//mis aligned certificate chain, return false so we do not accept this certificate
if (c != cPrivate) return false;
}
return found;
}