Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"The remote certificate is invalid according to the validation procedure" using HttpClient

Can't solve the problem with certificate validation.

There's Web API server, that uses HTTPS to handle requests. Server's certificate has this certification path: RCA (root) -> ICA (intermediate) -> Web API server. RCA, ICA and Web API server are members of the same Active Directory domain.

Client application (desktop, computer is joined to the same domain) uses HttpClient to communicate with server and supports two scenarios:

  • connected to corporate network;
  • disconnected from corporate network (Internet access).

Both scenarios use basic authentication.
RCA and ICA certificates are placed in "Trusted Root Certification Authorities" and "Intermediate Certification Authorities" respectively for local computer account. RCA certificate is self-signed.

Now, when client is connected to corporate network, certificate validation works as expected, and user can "talk" to Web API.

When client is disconnected (only Internet connection is available), certificate validation fails with AuthenticationException ("The remote certificate is invalid according to the validation procedure").

I don't want to turn off certificate validation completely, but just need a way to tell validation system, that this particular certificate is valid. Also, client application uses SignalR, which by default uses it's own transport. Hence, this and this are not options.

Why placing RCA an ICA certificates to "Trusted..." and "Intermediate..." folders doesn't help?

Is there any workaround?

like image 745
Dennis Avatar asked Dec 18 '15 11:12

Dennis


3 Answers

The issue you are experiencing is because the subject CN presented by the certificate does not match the host name in the Uri.

Make sure that the certificate bound to the public IP address of the host does have a matching CN with the host name you are using to access the resource.

To easily verify, open the Url in a browser and view the certificate. The Issued to field should contain a FQDN and match the host name part in the Uri. In your case, it does not.

like image 181
Mihai Caracostea Avatar answered Nov 16 '22 22:11

Mihai Caracostea


Insert this piece of code on procedure body:

static void Main(string[] args)   
{
     ServicePointManager.ServerCertificateValidationCallback =
                delegate (object sender, X509Certificate certificate, X509Chain 
     chain, SslPolicyErrors sslPolicyErrors)
                {
                    return true;
                };
     ....
}
like image 12
Qosai Al Khaseeb Avatar answered Nov 16 '22 23:11

Qosai Al Khaseeb


The answer from @Qosai was unfortunately not enough for me, at least in a SignalR 3.1 client, as the websocket part also validates SSL certificates. ClientCertificateOptions needs to be set to Manual as well.

I found a post by a SignalR contributor that got me working:

_connection = new HubConnectionBuilder()
            .WithUrl(new Uri(hub_uri), options => {
                options
                    .Cookies
                    .Add(http_helper.loginCookie);

                var handler = new HttpClientHandler
                {
                    ClientCertificateOptions = ClientCertificateOption.Manual,
                    ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true
                };
                options.HttpMessageHandlerFactory = _ => handler;
                options.WebSocketConfiguration = sockets =>
                {
                    sockets.RemoteCertificateValidationCallback = (sender, certificate, chain, policyErrors) => true;
                };
            })
            .Build();

PS: If you still have issues, have a look at this article on how to enable logging properly. For my case it was a bit tricky because xUnit does not show console output. Therefore i enabled debugging logging to a file (not in the snippet)

like image 8
Paulo Neves Avatar answered Nov 16 '22 23:11

Paulo Neves