X509Certificate2.Verify() returns false always
c#, client-certificates, x509certificate2
Solution
According to the X509Certificate2.Verify documentation
This method builds a simple chain for the certificate and applies the base policy to that chain. If you need more information about a failure, validate the certificate directly using the X509Chain object.
Therefore I would try to build chain using this code (replace Log method with your own implementation, I was using Console.Writeline)
X509Chain chain = new X509Chain();
try
{
var chainBuilt = chain.Build(testClientCert );
Log(string.Format("Chain building status: {0}", chainBuilt));
if (chainBuilt == false)
foreach (X509ChainStatus chainStatus in chain.ChainStatus)
Log(string.Format("Chain error: {0} {1}", chainStatus.Status, chainStatus.StatusInformation));
}
catch (Exception ex)
{
Log(ex.ToString());
}
This code will tell you the reason why the certificate could not be verified. If you need to adjust chain policy then set `chain.ChainPolicy` property i.e.
chain.ChainPolicy = new X509ChainPolicy()
{
RevocationMode = X509RevocationMode.NoCheck,
VerificationFlags = X509VerificationFlags.IgnoreNotTimeValid,
UrlRetrievalTimeout = new TimeSpan(0, 1, 0)
};
Problem
Facing a really strange issue X509Certificate2.Verify() returning false for a valid certificate. Maybe some has already faced this strange scenario before and can shine some light on it. I am using openssl to generate client certificates for testing purposes. I create a Root CA and generate a client certificate based on that Root CA and add the Root CA to its chain. I load the Root CA and the Client Cert to the local certificate store and it seems ok there but when I load it from my NUnit code to test X509Certificate2.Verify() always returns false. Here is the code to load the Cert from the store: ``` X509Store store = new X509Store(StoreName.My); string thumbprint = "60 d1 38 95 ee 3a 73 1e 7e 0d 70 68 0f 2d d0 69 1e 9a eb 72"; store.Open(OpenFlags.ReadOnly); var mCert = store.Certificates.Find( X509FindType.FindByThumbprint, thumbprint, true ).OfType<System.Security.Cryptography.X509Certificates.X509Certificate>().FirstOrDefault(); if(mCert != null) { var testClientCert = new X509Certificate2(mCert); } ``` Here is the Client Cert that I have just generated: (the CRL url is accessible from my local machine correctly) ``` -----BEGIN CERTIFICATE----- MIIC7jCCAlegAwIBAgIBATANBgkqhkiG9w0BAQUFADBtMR0wGwYDVQQKExRWaXRh bEhlYWx0aCBTb2Z0d2FyZTElMCMGA1UECxMcVml0YWxIZWFsdGggU29mdHdhcmUg Um9vdCBDQTElMCMGA1UEAxMcVml0YWxIZWFsdGggU29mdHdhcmUgUm9vdCBDQTAe Fw0xNTAyMjcwODQ2MzNaFw0xNjAyMjcwODQ2MzNaMEUxHTAbBgNVBAoTFFZpdGFs SGVhbHRoIFNvZnR3YXJlMREwDwYDVQQLEwhQbGF0Zm9ybTERMA8GA1UEAxMIVGVz dFVzZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOkfyjX0PSnRYrBbCC8u rw7IiFdAUj6frPKEmt0TLAR/4g+NazKdGjRRqxE9mNwX/2zGhIcucfGDVwPtOtiV opicQEzGiSQkvAc+473MN5D6j3XtBYblALMeMyEYoh3LnHO4K+6kV6XE4BXV/2lV mAVgXGkZzaayd40DLvg48vPlAgMBAAGjgcUwgcIwCQYDVR0TBAIwADARBglghkgB hvhCAQEEBAMCB4AwCwYDVR0PBAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMCMDEG CWCGSAGG+EIBDQQkFiJPcGVuU1NMIENlcnRpZmljYXRlIGZvciBTU0wgQ2xpZW50 ME0GA1UdHwRGMEQwQqBAoD6GPGh0dHA6Ly9wbGF0Zm9ybWRhc2hib2FyZC5ubC52 aXRhbGhlYWx0aC5sb2NhbC9wb3J0YWwvY3JsLmNybDANBgkqhkiG9w0BAQUFAAOB gQBXYSmZaVu6vnyl94SO4qpNOutsUm4p7fQHehljhZ+aRrXE10rivWCt4g0k961E PDsp4J0DR6uth6et42pBp8v2gFIGSQY/F7NhmOAsOJvM7z0oIBxMLcclIDTygbRp KjZZpNjvf+YJasbidosiL4VSeRiCZ+HPzvKDb3wNeafoZA== -----END CERTIFICATE----- ``` And here is the CRL file that gets download when I access it from the browser: ``` -----BEGIN X509 CRL----- MIIBMjCBnDANBgkqhkiG9w0BAQUFADBtMR0wGwYDVQQKExRWaXRhbEhlYWx0aCBT b2Z0d2FyZTElMCMGA1UECxMcVml0YWxIZWFsdGggU29mdHdhcmUgUm9vdCBDQTEl MCMGA1UEAxMcVml0YWxIZWFsdGggU29mdHdhcmUgUm9vdCBDQRcNMTQwODA3MTQz OTIyWhcNMTQwOTA2MTQzOTIyWjANBgkqhkiG9w0BAQUFAAOBgQA8MSxAorbxpdDm 1IA2Aqjb/OkZydua1Tm5k5KtHknI4zyYPZb3GzO0eRygpKBSAqtYkxDI6eCv6xgf +anXT56md+cPGZ+2YvSicxqwP2GL2kymc9mVMTiQieioS1/7apjCIjZEgWxqf3Up zvy/kNQRg3lII8hYu0idGs9byKZJFQ== -----END X509 CRL----- ```