0

We have a C# class that is used by both a server and web app to get info from a 3rd party web service. Currently the service is accessible via http and https. We are trying to get the class to work with https because we believe the 3rd party will only allow https access in the future.

This is our code that works:

using (HttpClient httpClient = new HttpClient())
        {
            try
            {
                //specify to use TLS 1.2 as default connection
                System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

                var uri = new Uri(url);
                string uriStr = uri.ToString();
                string msg = $"uri: {uriStr}";

                ApplicationLogger.Singleton.LogMessage(LogCategories.General, System.Diagnostics.TraceEventType.Verbose, msg, "GetUrlResponseString - uri");

                var task =  httpClient.GetStringAsync(uri);
                task.Wait();

                string taskBools = "";
                if (task.IsCompleted)
                    taskBools = "Task Completed";
                else if (task.IsFaulted)
                    taskBools = "Task Faulted";
                else if (task.IsCanceled)
                    taskBools = "Task Canceled";

                string taskStatus = task.Status.ToString();
                msg = $"Task Status: {taskBools} taskStatus: {taskStatus}";

                ApplicationLogger.Singleton.LogMessage(LogCategories.General, System.Diagnostics.TraceEventType.Verbose, msg, "Task Status");

                string listOfSites = (string)task.Result;
                ApplicationLogger.Singleton.LogMessage(LogCategories.General, System.Diagnostics.TraceEventType.Verbose, 
                    $"listOfSites: {listOfSites}", "GetUrlResponseString - listOfSites");

                return listOfSites;
            }

On your site and others, we see mention of the SecurityProtocolType.SystemDefault. From my research, we'd like to use that because it is supposed to get the security setting from the operating system. We'd like our server admins to handle that. That way we wouldn't have to change the code in the future.

Now I know we may have to re-compile and deploy the class library when .Net supports Tls13, Tls14 and etc. But it still eliminates a code change.

Anyways, our server admin can't get it to work with the SecurityProtocolType.SystemDefault setting. She wants to know what the program thinks is the current security setting. Is there something that I can't examine/print to see what it is?

PabloCruise
  • 75
  • 1
  • 9
  • The default is `Ssl3` and `Tls1.0`. If you have `.Net FrameWork 4.7.2`, the `HttpClientHandler` can `get; set;` it's [SslProtocols](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclienthandler.sslprotocols?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query%3FappId%3DDev15IDEF1%26l%3DEN-US%26k%3Dk(System.Net.Http.HttpClientHandler.SslProtocols);k(TargetFrameworkMoniker-.NETFramework%26f%3D255%26MSPPError%3D-2147217396&view=netframework-4.7.2)) property, which is readable at run-time. 4.7.1 has the property but it's not implemented. – Jimi Aug 06 '18 at 17:14
  • You are right about 4.7.1. Tried this with 4.7.2 strSslProtocols = clientHandler.SslProtocols.ToString(); Says: None in the log – PabloCruise Aug 06 '18 at 18:32
  • After a failed Ssl handshake? If that's so, unfortunatly the HttpClient doesn't set the Response when the transaction is refused. You'ld have to get the underlying `ConnectStream` to get to the `NetworkStream` down to the `SslProtocol`. I posted a method to get the negotiated Ssl protocol here: [Which TLS version was negotiated?](https://stackoverflow.com/questions/48589590/which-tls-version-was-negotiated?answertab=active#tab-top) `(...)`. – Jimi Aug 06 '18 at 19:22
  • One dirty thing you could do, is to enable all protocols (they're flags), combining all the enumeration values available, then let the Ssl handshake decide which one to use. After the negotiation has terminated successfully, check what protocol has been agreed upon and if you don't like it, drop the connection. I have pre-processor method that sets the Ssl protocols based on different conditions (both pre and post a connection attempt). You need to have a static HttpClient setup for this, possibly in a Lazy (`Lazy`) constructor/configuration. – Jimi Aug 06 '18 at 19:23

0 Answers0