5

A server has disabled TLS 1.0/1.1. The client is an XBAP application running in Internet Explorer. It looks like the PresentationHost tries to establish a TLS 1.0 connection but fails because the server refuses it. Can I somehow force (e.g. programmatically or config file) PresentationHost to use TLS 1.2? I know that it's possible to set the client's registry accordingly (set SchUseStrongCrypto to 1) but I would like to avoid the user to configure anything.

Dunken
  • 8,481
  • 7
  • 54
  • 87

3 Answers3

2

In general I would expect the client to negotiate the highest TLS level that is supported and enabled. Since your connection fails after trying only TLS 1.0, I suspect TLS1.1 and TLS1.2 may not be supported and enabled on the client side.

Applications built with .Net 4.7 will default to SecurityProtocolType.SystemDefault, which is chosen by the operating system and may be modified through registry settings. SecurityProtocolType is defined as:

... the enumerated type for the SecurityProtocol property. Use this enumeration to determine your transport security protocol policy when you're using HTTP APIs in the .NET Framework such as WebClient, HttpWebRequest, HttpClient, and SmtpClient (when using TLS/SSL).

Earlier framework versions may default to a specific protocol type regardless of what the OS default is set to. Under most circumstances they should still try other protocols if they are enabled.

If the behavior you are seeing is not what you want then the first thing is to ensure that both the targeted framework version and the OS version are capable of supporting the security protocol type you want to enable (e.g., TLS 1.2). A list of protocol version support by OS version is here.

If the targeted version of .Net and the OS version both support TLS1.2, then you should be able to force connections to ONLY accept TLS1.2 by setting the ServicePointManager security protocol type. To restrict it to a single protocol (e.g., TLS1.2), just set it before making a web call:

.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

You can OR protocols together, so you can enable TLS 1.1 and 1.2 while leaving already-enabled ones intact by doing something like this:

System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

If you just want to turn off an older protocol like TLS1.0 while permitting others (including future releases) then you could do something like this:

System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Tls;

The setting can be made on the fly or it can put put into a global config like Global.asax Application_Start if you wish.

Documentation for the ServicePointManager.SecurityProtocol is here.

For completeness I note that if you must target .Net4.0 you can still use the above techniques to specify TLS1.2 if you simply install .Net4.5 alongside the targeted version. It's even possible to do so with older versions of the framework if you update a couple of the .dll files. Instructions are here.

It's worth noting that there are other ways this whole thing can fail depending on the certificate configurations, registry settings, and which updates are installed.

I understand that you want to stay away from user settings, but there are browser settings that may also affect this behavior. See the MSDN blog post here which addresses settings for Firefox as well as IE.

On the client side, you can check this in the browser settings. If you are using IE on any of the supported Windows OS listed above, then in IE, browse to Tools -> Internet Options -> Advanced. Under the Security section, you would see the list of SSL protocols supported by IE. IE supports only those security protocol versions, which is supported by the underlying SCHANNEL component of the OS.

EDIT:

If the information above isn't sufficient to correct the problem , then it's time to fire up WireShark and look at the TLS negotiation directly. Just set your capture filter to 'SSL,' choose the IP address you want to track, and use the menu dropdown or keyboard shortcut Ctrl-Alt-Shift-S to follow the SSL Stream. You may find that the problem is on the server side after all, or perhaps you'll see a certificate problem on one side or the other.

It's pretty fast to do this even if you don't normally use WireShark, and there are plenty of tutorials available. I like one at the cisco site here, which I'll quote briefly in case the link goes away:

Following the ssl stream will give you a clear picture of the whole TLS hand shake and exchange of public keys, cert up to the exchange of symmetric key used for further encryption.

... the first thing that always happens when connecting using https is the client (your browser) announcing its cipher capabilities, it basically tells the server you are connecting to what security algorithms you are capable of. This is shown in the screen shot below

enter image description here

Craig.Feied
  • 2,617
  • 2
  • 16
  • 25
  • Many thanks. The connection doesn't negotiate the highest possible TLS level (otherwise it would work). I also tried to set `SecurityProtocolType.Tls12` but this too doesn't help in this case. – Dunken Oct 25 '18 at 09:46
  • @Dunken if you could explain what you mean by "doesn't help" then I may be able to assist a bit more. TLS negotiation does work as documented, so perhaps your operating system or .net version doesn't support TLS1.2? I did show workarounds for those scenarios too... – Craig.Feied Oct 25 '18 at 19:37
  • @Dunken I've added info about how to look at the negotiation in WireShark. If that still doesn't resolve the problem, maybe you could post a small functioning example that we can run to observe your problem? – Craig.Feied Oct 25 '18 at 19:56
0

Seems to be an issue with the underlying IE version.

Can you confirm the user-agent?

As well do perform a testssl.sh.

To use the tool navigate to https://testssl.sh

aarvee
  • 139
  • 1
  • 5
0

As Craig.Feied mentioned it is necessary to enable the higher level secure protocols explicitly for an XBAP application.

By default, even under .NET 4.7.2 the System.Net.ServicePointManager.SecurityProtocol is set to Ssl3 and Tls as the only supported protocols for XBAP applications.

To enable the TLS 1.1 or 1.2 protocols for your XBAP application add a using statement to include System.Net and add a line similar to:

System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

NOTE: Standard WinForms applications will negotiate TLS 1.2 without requiring the additional line of code but XBAP applications aren't quite as smart

Greg Pugh
  • 31
  • 5