I need to validate a certificate(X509Certificate2) the same way it´s validated before it is used for communication.
The X509Certificate2.Verify() will in this case return true while the certificate is not issued to the server it is installed on.
Is there any finished code block to do a full validation of the X509 certificate?
Regards
Edit : This is the code I have tried with :
var certificate = GetServerCertificate(CertificateStore,CertificateLocation,Thumbprint);
if(certificate != null)
{
if(certificate.Verify())
_logger.Log(NLog.LogLevel.Info, $"Yes");
else
_logger.Log(NLog.LogLevel.Info, $"No");
}
The X509Certificate2.Verify() will in this case return true while the certificate is not issued to the server it is installed on.
The Verify
method doesn't check anything about hostnames. It verifies that
It's exactly equal to
using (X509Chain chain = new X509Chain())
{
// Use the default vales of chain.ChainPolicy including:
// RevocationMode = X509RevocationMode.Online
// RevocationFlag = X509RevocationFlag.ExcludeRoot
// VerificationFlags = X509VerificationFlags.NoFlag
// VerificationTime = DateTime.Now
// UrlRetrievalTimeout = new TimeSpan(0, 0, 0)
bool verified = chain.Build(cert);
for (int i = 0; i < chain.ChainElements.Count; i++)
{
chain.ChainElements[i].Certificate.Dispose();
}
return verified;
}
Is there any finished code block to do a full validation of the X509 certificate?
If "full validation" just means all the things Verify
does, then yes. If you also care that it's valid for use as a TLS client certificate (or TLS server certificate) then you would use the longer form (using X509Chain directly) and add an application policy requirement before calling chain.Build:
// See if it's valid as a TLS server
chain.ChainPolicy.ApplicationPolicy.Add(new Oid("1.3.6.1.5.5.7.3.1"));
// Alternatively, if it's valid as a TLS client
chain.ChainPolicy.ApplicationPolicy.Add(new Oid("1.3.6.1.5.5.7.3.2"));
The hostname is much harder. Client certificates don't have validatable names, it's just up to what the server does with it. Server certificates have hostname matching against SAN/Subject-CN, but there's nothing built-in that does that check other than just connecting with TLS (SslStream
).
Update (2023-09-08): Hostnames can be verified on X509Certificate2 instances starting in .NET 7, via the MatchesHostname method.