My program contains 2 root certs I know and trust. I have to verify certs of trustcenters and "user" certs issued by the trustcenters which all originate from these 2 root certs.
I use X509Chain class to verify but that only works if the root cert is in the windows certificate store.
I'm looking for a way to verify the certs without importing theeses root certs - somehow tell the X509Chain class that I do trust this root certs and it should check just the certs in the chain and nothing else.
Actual code:
X509Chain chain = new X509Chain();
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.ExtraStore.Add(root); // i do trust this
chain.ChainPolicy.ExtraStore.Add(trust);
chain.Build(cert);
Edit: It's a .NET 2.0 Winforms application.
I opened an Issue on dotnet/corefx and they replied as follows:
If AllowUnknownCertificateAuthority is the only flag set then
chain.Build()
will return true if
The chain correctly terminated in a self-signed certificate (via ExtraStore, or searched persisted stores)
None of the certificates are invalid per the requested revocation policy
All of the certificates are valid under the (optional) ApplicationPolicy or CertificatePolicy values
All of the certificates' NotBefore values are at-or-before VerificationTime and all of the certificates' NotAfter values are (at-or-)after VerificationTime.
If that flag is not specified then an additional constraint is added:
The self-signed certificate must be registered as trusted on the system (e.g. in the LM\Root store).
So, Build() returns true, you know that a time-valid non-revoked chain is present. The thing to do at that point is read
chain.ChainElements[chain.ChainElements.Count - 1].Certificate
and determine if it is a certificate that you trust. I recommend comparingchainRoot.RawData
to abyte[]
representing a certificate that you trust as a root in context (that is, byte-for-byte compare rather than using a thumbprint value).(If other flags are set then other constraints are also relaxed)
So you should do it this way:
X509Chain chain = new X509Chain();
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.ExtraStore.Add(root);
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
var isValid = chain.Build(cert);
var chainRoot = chain.ChainElements[chain.ChainElements.Count - 1].Certificate;
isValid = isValid && chainRoot.RawData.SequenceEqual(root.RawData);