Fallback to System Certificate Store when CA Certificate Path Is Not Present#991
Fallback to System Certificate Store when CA Certificate Path Is Not Present#991dckorben wants to merge 6 commits into
Conversation
| @@ -182,7 +182,33 @@ internal bool VerifyRemoteCertificate( | |||
|
|
|||
| // If CA Certificate is specified then validate against the CA certificate, otherwise it is validated against the installed certificates | |||
There was a problem hiding this comment.
Notable that this comment SAYS it validates against installed certificates but that is actually not true. It validates against installed certificates if it is a HTTPS/TLS connection, which was probably the intended meaning. If you specify a certificate but not a CA, it just fails. In the case of #990, you can specify a certificate from a Public CA but then validation fails and because many CAs use a lineage of certificates you cannot validate the chain with the existing configuration options.
|
I do see a potential issue here where it doubles up the certificate chain validation for TLS/HTTPS connections because the function |
|
@dckorben yes it works now if I don't specify CA certificate and it checks it agains the installed ones. |
|
Are you a Linux test by chance? |
The good aspect of this is you won't have to manage the CA key expirations manually. So, it's an improvement in function as well. |
|
nope, windows |
I've not understood this sentence nor the nuances of the issue, but just to point out: SslStream already performs validation, and RemoteCertificateValidationCallback is just to perform extra validation on top. So at the very least, it seems this method is missing a Definitely could be missing something, but I believe it should/could look something like: static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
{
// Cert is trusted. No need to do anything else.
// (SslStream also already checks for server/client auth EKU)
return true;
}
if (_socketSettings.ValidateCertificates == false)
return true;
X509Certificate2 caCert = ...;
using var customChain = new X509Chain();
customChain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
customChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
customChain.ChainPolicy.ApplicationPolicy.Add(new Oid("1.3.6.1.5.5.7.3.1", "1.3.6.1.5.5.7.3.1")); // server auth EKU
customChain.ChainPolicy.CustomTrustStore.Add(caCert);
bool isValid = customChain.Build((X509Certificate2)certificate);
if (!isValid)
{
foreach (var status in customChain.ChainStatus)
{
// Log errors etc.
}
}
return isValid;
} |
That would probably work. Let me take another look. |
|
Hi guys, I have nothing to add (I hate this SSL stuff!), but wanted to let you know I'm paying attention and looking forward to merging when you get it figured out. |
"Fixes" #990
This isn't final, too duplicative. Need someone to verify it works on Windows/Linux as we've been bitten by behavior differences before and I don't have an admin box I can trust the generated CA with.
@dimaaik27 Please verify this works in your implementation before I clean up the code.
[@gbirchmeier added: resolves #990 ]