1

I'm working on a .NET Core app where verification of a 3rd party SSL certificate (occurring across a VPN) is failing (the server cert isn't properly signed with a root CA so can't be verified using openssl, which I'm using).

It's easy enough to disable verification for an HttpClient I manually create. Something like this, as described in bypass invalid SSL certificate in .net core:

using (var httpClientHandler = new HttpClientHandler())
{
   httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
   using (var client = new HttpClient(httpClientHandler))
   {
       // Make your request...
   }
}

In my case though, I'm using a 3rd party DLL to make a connection, so the internals of how it does the request are hidden, and I have no access to disable SSL verification for the connection. Is there a way in .NET Core 3.1 I can completely disable SSL verification for any requests from the application?

Chris Halcrow
  • 28,994
  • 18
  • 176
  • 206
  • 1
    why would SSL validation over a VPN fail? – Mitch Wheat Jan 19 '21 at 01:04
  • @Mitch Wheat it's unclear why the validation is failing. The connection requires a client SSL certificate, which is usually registered in the Windows CA store, but in my case I'm using Linux - so there's likely a compatability issue with the service I'm trying to connect to. There's no indication though of the exact cause. It's taken days to try to determine the cause, which is why I need to try something else. – Chris Halcrow Jan 19 '21 at 01:16
  • 1
    Can you not grab the certificate and trust it as root? – Charlieface Jan 19 '21 at 01:18
  • this may help u..https://stackoverflow.com/questions/62990470/how-to-disable-ssl-certificate-validation-upon-openid-connect-in-net-core-3-1 – MD. RAKIB HASAN Jan 19 '21 at 05:14
  • @MitchWheat, I found out that the reason we can't validate the CA as a valid, trusted CA is that we're developing in C# on Linux. Apparently, this causes OpenSSL to be used for validation. Openssl can only trust certificates with BasicConstraint CA set to true. The system we're trying to connect to does not have this set and cannot be trusted in openssl. – Chris Halcrow Feb 01 '21 at 23:15
  • @Charlieface, the server certificate is self-signed, and generated without a root cert. I'm not sure what you mean as 'grab the certificate and trust it as root' - my SSL knowledge isn't great. We have a certificate that is the public certificate used to validate the server cert (for the system we're connecting to). If I try to specify in code, or via the OS that this should be used to validate the server CA cert, it doesn't work. – Chris Halcrow Feb 01 '21 at 23:17
  • Not familiar enough with OpenSSL to say how you would do that. But in Windows you can have a Trusted Root Certificate. There are various ways to get a copy of the public key for this, not least by opening the url in a browser – Charlieface Feb 01 '21 at 23:30
  • @Charlieface that's correct. This works. The reason is that Windows doesn't strictly enforce SSL standards and instead accepts this as a reasonable indication of trust. OpenSSL requires that the server certificate is correctly configured. In this case, the 3rd part server cert is self-signed, without using any recognised root CA. That's why a workaround is required, to work with OpenSSL. – Chris Halcrow Feb 02 '21 at 04:30
  • @Charlieface I've explained in my answer why the certificate can't be trusted as root, and a workaround to allow an SSL connection without the verification step. – Chris Halcrow Feb 04 '21 at 01:45

1 Answers1

0

IMPORTANT - this is a hacky workaround that circumvents a basic principle of SSL connection i.e. verification of the certificate origin. It's only useful if you have a situation where a self-signed certificate used on a server does not allow correct verification for some reason. When following standard practice, the described workaround should only ever be done in development or test scenarios.

I found that the server is using a self-signed certificate that is not fully acting as a CA. openssl is being utilised on the client Linux server when establishing the SSL handshake (which more strictly enforces SSL standards than Windows), and this expects a properly signed CA chain for the x509 certificate. This doesn't exist in this case, so the certificate can't be trusted as root on the client's Linux server, and that's why the verification isn't working.

I've found indications that there is no global option to disable the SSL validation (or strictly speaking 'verification') step in .NET Core.

Instead, on the client's Linux host I proxy a tcp connection to an SSL one using a stunnel running within the app's kubernetes pod, and turn off SSL validation via switching off chain verification in the stunnel config something like:

[destination.FQDN.com]
client = yes
accept = 127.0.0.1:1234
connect = $remote:1234
verifyChain = no

From appsettings.json I then connect to tcp:127.0.0.1:1234 (i.e. the local receiver end of the stunnel). The stunnel then successfully establishes the encrypted channel to ssl:127.0.0.1:1234.

Chris Halcrow
  • 28,994
  • 18
  • 176
  • 206