Ramaravishankar
Ramaravishankar

Reputation: 3

HttpListenerRequest.GetClientCertificate() not returning the complete certificate chain

I have a web server implemented using HttpListener in C#, there is a Go client which talks to this server. As part of the requirement I need to validate the certificates sent from the client on the server and I'm sending a certificate chain from the client. I found the method HttpListenerRequest.GetClientCertificate() to get the certificates on the server but I am able to receive only the leaf certificate but not the entire chain which is blocking me to perform the chain validation. Is there a way to receive the entire chain using HttpListener as the server.

PS: I tried sending the same certificate chain to a Go server and Go has ssl callback handler(VerifyPeerCertificate) in Tls Config using which I am able to read the entire certificate chain. I just want to acheive this with the existing HttpListener server I have in C#.

Edit: My client certificate is a chain (client cert + Intermediate CA + Root CA). I have the Root CA pre stored in the Trusted Root Certification Authorities. I need to get the Intermediate CA in the Windows Trust Store so that I can build the chain for the client certificate and as I can't pre store the Intermediate CA the idea is to send the chain from the client and extract the Intermediate CA when the client talks to the server. As I am able to receive the complete chain using a Go server with the same client I can confirm that client sends the chain always but somehow the methods we have in C# for HttpListener seems to ignore the chain.

Upvotes: 0

Views: 374

Answers (1)

Hazrelle
Hazrelle

Reputation: 856

Normally the client is just sending its client certificate, then it is the server responsibility to check that the client certificate is trusted. If anyone can send a client certificate with the complete chain, then the server can accept any certification authority (including any compromised). So the certificate of the certification authority that has emitted the client certificate must be trusted on the server to ensure this authority is trusted and the server can request this authority to ensure the client certificate has not been revoked. On Windows this is done by adding the certificate of the certification authority to the Trusted Root Certification Authorities store.

The HttpListenerRequest.GetClientCertificate() source loads just one certificate.

It's on the server side to check the complete chain. The server must be able to connect to the AIA that has signed the client certificate to download the intermediate CA.

            var chain = new X509Chain();
            chain.ChainPolicy = new X509ChainPolicy()
            {
                DisableCertificateDownloads = false,
                RevocationFlag = X509RevocationFlag.EntireChain,
                RevocationMode = X509RevocationMode.Online,
                UrlRetrievalTimeout = TimeSpan.Zero,
                VerificationFlags = X509VerificationFlags.AllFlags
            };

You may try to implement your own HttpListenerRequest and use it as a middleware in the pipeline.

Upvotes: 0

Related Questions