Dombat


Software Engineering, Security, Management & Leadership

Dombat

Self-Signed Certificates and Could not establish trust relationship for the SSL/TLS secure channel.

10th February 2019

I've encountered this using RestSharp and other clients. The standard advice from stackoverflow seems to be to put in this code to ignore the errors;

ServicePointManager.ServerCertificateValidationCallback +=
        (sender, certificate, chain, sslPolicyErrors) => true;

This is a bit dodgy.

Firstly, if the system is to go into production, you don't want to be ignoring certificate errors.  You could at least wrap it with a pre-processor directive.

#if DEBUG
    ServicePointManager.ServerCertificateValidationCallback +=
              (sender, certificate, chain, sslPolicyErrors) => true;
#endif

Even this is dodgy, since the code that is released will not have been properly tested. It is also a systemwide setting, so other calls will be affected too.

While reading about the ServicePointManager, I came across this which is quite interesting for some developers encountering issues while upgrading .NET versions:

The .NET Framework 4.6 includes a new security feature that  blocks insecure cipher and hashing algorithms for connections.  Applications using TLS/SSL through APIs such as HttpClient, HttpWebRequest, FtpWebRequest, SmtpClient, SslStream, etc. and targeting .NET Framework 4.6 get the more-secure behavior by default.  
Developers may want to opt out of this behavior in order to  maintain interoperability with their existing SSL3 services or TLS w/  RC4 services. This article explains how to modify your code so that the new behavior is disabled.

from MSDN.

Trusting The Certificate

If you're working with a 3rd party API while developing code and they use self-signed certicates. You may want to consider trusting their certificate rather than putting in hacks like the code at the top of the page. Firstly, I would question your 3rd party as to why they are using self-signed certificiates when you can get free one's from LetsEncrypt, but sometimes thats the way it is. You only do this in non-production environments which are not public.

If you put the API adress in a browser, you'll see an error like this

problem with this websites security certificate screenshot

Click continue to this website and then click the certificate warning icon in the address bar. You see a popup message like this

Clicking the certificate error shows a untrusted certificate warning

Click to view certificates.

Read the details carefully. In this we see it says that it cannot be verified up to a trusted certification authority. If we click the details tab we will be able to see the certitifcate chain

In my chain we have three certitficates. You can see the red X icon on the top level is where the problem is.

When I click on the top certificate the messages tells me exactly what is wrong - "The CA root certificate is not trusted because it is not in the Trusted Root Certification Authorities store". Your message may be different, but to resolve this issue I need to add this certificate to the Trusted Root Certification Authorities store on this machine (and anywhere I am doing the testing).

Click View Certificate

Click Install Certificate, the wizard will open. You need to decide whether to install just for you or other users. In my case we had multiple testers using the same server so I wanted to install in the Local Machine store.

Certificate import main screen where you choose current user or local macgine certificate stores.

Click Next, then choose "Place all certificates in the following store" then hit the Browse button.

I'm choosing to install in the Trusted Root Certification Authorities store. This was clear when I clicked the error in the certificate chain earlier, so be sure to read the error messages carefully.

Click OK on the correct store, then Next. After a few seconds the "Import was successful" dialogue appears. This can often appear behind the current window just to confuse you more!

Now that the certificate has been installed, close the browser and reopen it. Then visit the URL again. You should be able to get to there without the error.

Only do this on dev/test environments if you really need to. Ideally work with the 3rd party to use valid certificates.

Software Engineer with interests in security and business processes.

View Comments