Andrés Villenas

Software Engineering, .Net Development, Sitecore, and more fun.

Sitecore WFFM and TLS

Some weeks ago, the infrastructure team in charge of monitoring security issues in the servers of one company alerted us about that TLS 1.0 and 1.1 was still enabled in some Windows Servers. The description of this issue is at https://docs.microsoft.com/en-us/security/solving-tls1-problem.

In those servers, there were two Sitecore 8.2 (.Net 4.5.2) applications running. One of them uses the Web Forms For Marketers module to enable two forms that stopped to work after the TLS 1.0 and TLS 1.1 were disabled in the servers.

After checking the logs, the following exception was found:

Exception: System.ComponentModel.Win32Exception
Message: The client and server cannot communicate, because they do not possess a common algorithm
Source: System
  at System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPIInterface SecModule, String package, CredentialUse intent, SecureCredential scc)
  at System.Net.Security.SecureChannel.AcquireCredentialsHandle(CredentialUse credUsage, SecureCredential& secureCredential)
  at System.Net.Security.SecureChannel.AcquireClientCredentials(Byte[]& thumbPrint)
  at System.Net.Security.SecureChannel.GenerateToken(Byte[] input, Int32 offset, Int32 count, Byte[]& output)
  at System.Net.Security.SecureChannel.NextMessage(Byte[] incoming, Int32 offset, Int32 count)
  at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
  at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
  at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
  at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
  at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
  at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
  at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
  at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
  at System.Net.ConnectStream.WriteHeaders(Boolean async)

With this information, it was clear that disabling TLS 1.1 in the server caused the client, and the server was not able to interchange information because there was not another alternative, like TLS 1.2. To fix this, we had to enabled TLS 1.1 and TLS 1.2 explicitly in the application using the following code:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12

The previous line of code was required because depending on the .Net Framework version, TLS 1.2 may not be enabled and also some old web browsers don't support it.

  1. .NET 4.6 and above. TLS 1.2, it is supported by default.
  2. .NET 4.5. TLS 1.2, it is supported, but it’s not a default protocol. You need to enable it using the following line in the Global.asax file, in the Application_Start event.
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
  3. .NET 4.0. TLS 1.2, it is not supported, but if you have .NET 4.5+ installed, then you still can activate it with the following line.
    ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

I hope this use useful if you have the same issue.

That's it for today.

Until the next post!