Search code examples
c#securityssl-certificatex509

X509Chain building using a custom certificate store


In order to perform SSL certificate validation, I am assigning a callback to System.Net.ServicePointManager.ServerCertificateValidationCallback and then I'm trying to build the X.509 chain on my own to check if the server certificate was issued by a collection of CA's I trust.

I understand I can expand the collection of certificates to be used during chain build (by adding new items to X509Chain.ChainPolicy.ExtraStore) - but that is used to trust additional certificates that are not in the local certificate store.

How can I actually restrict the chain building to a given store I build programatically myself? I couldn't find a way to use a customized X509Store object to be used when calling X509Chain.Build(X509Certificate2).


Solution

  • AFAIK, there is no way to restrict a set of trusted root (trusted anchors) in .NET. However, you can call native (C++-like) CryptoAPI functions via interop.

    Basically, you will need to use CertCreateCertificateChainEngine function and use customized input chaining engine configuration structure: CERT_CHAIN_ENGINE_CONFIG.

    You will need to create a virtual (without explicit registration in Windows Certificate Store) store, add a set of trusted certificates of your choice. Get store handle/pointer and pass it in the hRestrictedRoot parameter in the CERT_CHAIN_ENGINE_CONFIG object. In this case, default root store will not be used. The function returns a handle to HCERTCHAINENGINE which can be used then in CertGetCertificateChain function call (where actual chain validation occurs).