As the title states i want to know how the certificate chain is build internaly.
I have a self signed root certificate (CA) und an incoming user certificate, which supposedly has been signed by my root, which is what i have to test. Testing a X509Certificate2 can be done with the X509Certificate2.Verify() method, which uses the X509Chain with some standard settings. To have full control over the process i am using the X509Chain directly. As my root is not installed on the machine (not in trusted root certificate store) i am adding it to the ExtraStore of the ChainPolicy.
The whole magic happens within X509Chain.Build() method, where i pass my 'to be tested' user certificate. The chain gets build, starting with the passed certificate and ending with the self signed root. But how exactly? How does one test wether a certificate has been signed by one or another root? Does it use digital signatures internally?
I tried to debug the whole thing but ended at an DLL import, which uses the CertGetCertificateChain method from Libraries.Crypt32. That is C++ stuff, which exceeds my domain of knowledge.
Simplified code so far:
using (var chain = new X509Chain
{
ChainPolicy =
{
RevocationMode = X509RevocationMode.NoCheck,
RevocationFlag = X509RevocationFlag.ExcludeRoot,
VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority,
VerificationTime = DateTime.Now,
UrlRetrievalTimeout = new TimeSpan(0, 0, 0)
}
})
{
chain.ChainPolicy.ExtraStore.Add(authority);
if (!chain.Build(signedCertificate))
{
//Errorhandling
}
//Root certificate should always be last in the X509ChainElements collection
var isSignedByCorrectRootCert =
chain.ChainElements
.Cast<X509ChainElement>()
.Last()
.Certificate.Thumbprint == authority.Thumbprint;
if (!isSignedByCorrectRootCert)
{
//Errorhandling
}
}