0
votes

We have a WCF client and server which communicate over a WCF NetTcpBinding with Streamed Transfermode where the client sets up the WCF NetTcpBInding with these relevant settings:

TransferMode = TransferMode.Streamed
Security.Mode = SecurityMode.Transport
Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate
Security.Transport.SslProtocols = System.Security.Authentication.SslProtocols.None

According to https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls, SslProtocols.None ensures that WCF uses the operating system default setting when using the NetTcp transport.

All our Windows hosts are configured to only allow TLS 1.2. This has been configured using the Windows registry and setting all server and client keys to disabled for SSL 2.0, SSL 3.0n TLS 1.0 and TLS 1.1 and enabled only for TLS 1.2 at location: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols, as described at https://docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings.

Additionally, the app.config files of our WCF client and server contain this runtime entry (as documented on https://docs.microsoft.com/en-us/configmgr/core/plan-design/security/enable-tls-1-2):

<configuration>
  <runtime>
  <AppContextSwitchOverrides value="Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols=false;Switch.System.Net.DontEnableSchUseStrongCrypto=false" />
  </runtime>
</configuration>

When the WCF client is running on Windows 10 (build 1809), and the server on Windows Server 2019 LTSC, .NET version 4.7.2, WCF communication works fine.

When both the WCF client and server are running on Windows Server 2019 LTSC, .NET 4.7.2, communication fails with this exception:

Message: A call to SSPI failed, see inner exception.
Title:The file information could not be gathered.
Inner Exception 1: A call to SSPI failed, see inner exception.
Inner Exception 2: The client and server cannot communicate, because they do not possess a common algorithm

Server stack trace: 
   at System.ServiceModel.Channels.SslStreamSecurityUpgradeInitiator.OnInitiateUpgrade(Stream stream, SecurityMessageProperty& remoteSecurity)
   at System.ServiceModel.Channels.StreamSecurityUpgradeInitiatorBase.InitiateUpgrade(Stream stream)
   at System.ServiceModel.Channels.ConnectionUpgradeHelper.InitiateUpgrade(StreamUpgradeInitiator upgradeInitiator, IConnection& connection, ClientFramingDecoder decoder, IDefaultCommunicationTimeouts defaultTimeouts, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.StreamedFramingRequestChannel.SendPreamble(IConnection connection, TimeoutHelper& timeoutHelper, ClientFramingDecoder decoder, SecurityMessageProperty& remoteSecurity)
   at System.ServiceModel.Channels.StreamedFramingRequestChannel.StreamedConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
   at System.ServiceModel.Channels.StreamedFramingRequestChannel.StreamedFramingRequest.SendRequest(Message message, TimeSpan timeout)
   at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
   at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

We were able to resolve the problem by explicitly setting Security.Transport.SslProtocols when setting up the client NetTcpBinding instead of letting the Operating System decide, as such:

Security.Transport.SslProtocols = System.Security.Authentication.SslProtocols.Tls12 Or System.Security.Authentication.SslProtocols.Tls11 Or System.Security.Authentication.SslProtocols.Tls Or System.Security.Authentication.SslProtocols.Ssl3

We don't understand why this solution works, as we expect this fix to have the same effect as letting the operating system choose.

With only TLS 1.2 allowed on all hosts, how can communication fail when both client and server are running on Windows Server 2019 and not chen the client runs on Windows 10? There is nothing else than TLS 1.2 to default to. How can it be investigated which protocol Windows defaults to?

1

1 Answers

0
votes

First of all, in this official article, it is not recommended that we specify or interfere with the SSL/TLS version that the operating system chooses to use. Do not disable some SSL/TLS versions using the Windows registry or other methods.
https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls
In my opinion, the version of SSL/TLS used by the server and client requires a process of negotiation. When the client does not disable another version of the protocol, even if the SSL/TLS version is specified on the client-side, it is determined by the negotiation process.
Besides, we should check the SSL/TLS version used during the communication by using the Wireshark network protocol analyzer.
https://www.wireshark.org/
enter image description here
Feel free to let me know if there is anything I can help with.