WCF: certificate trust list (CTL) issue with window Server 2012 R2 and Window 8.1
Problem Description: We have a WCF service https://localhost:38215/Service1.svc . We are accessing this service over SSL and using client certificate for authentication. We are getting 403 Forbidden for Windows Server 2012 R2 and Windows 8.1. The same service runs absolutely fine with Windows Server 2008 R2 and Windows 7 with same certificate and same settings. We are making request to service but not getting the response from there, instead 403 Forbidden is being returned .
Analysis: To understand the issue let collect the WCF+System.Net traces using following settings-
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Verbose, ActivityTracing" propagateActivity="true" >
<listeners>
<add name="xml"/>
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="xml"/>
</listeners>
</source>
<source name="System.Net">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.HttpListener">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.Sockets">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.Cache">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add name="xml"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:\temp\WCFTraces.svclog" />
<add name="System.Net" type="System.Diagnostics.TextWriterTraceListener"
initializeData="c:\temp\SNtrace.log" traceOutputOptions = "DateTime" />
</sharedListeners>
<switches>
<add name="System.Net" value="Verbose" />
<add name="System.Net.Sockets" value="Verbose" />
<add name="System.Net.Cache" value="Verbose" />
<add name="System.Net.HttpListener" value="Verbose" />
</switches>
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="true"
logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
</diagnostics>
</system.serviceModel>
</configuration>
Let’s analyze the traces collected. First we will see SNtrace.log. We see following highlighted warning.
System.Net.HttpListener Warning: 0 : [144] HttpListener#39451090::HandleAuthentication() - Received a request with an unmatched or no authentication scheme. AuthenticationSchemes:Anonymous, Authorization:<null>.
This indicated that service is not able to authenticate the request. Let’s see the WCF trace as this will show us the details about WCF service warning/error. WCF trace reporting a warning “Client certificate is required. No certificate was found in the request.”
This validates the point that client certificate is not passed to service so service is not authenticating the request. What is the reason this complete set up works for Window 7 and Windows Server 2008 R2 but is failing with Windows 8.1 and Server 2012 R2.
Cause:
When authentication of the client computer is required using SSL or TLS, the server can be configured to send a list of trusted certificate issuers. This list contains the set of certificate issuers which the server will trust and is a hint to the client computer as to which client certificate to select if there are multiple certificates present. In addition, the certificate chain the client computer sends to the server must be validated against the configured trusted issuers list.
Prior to Windows Server 2012 and Windows 8, applications or processes that used the Schannel SSP (including HTTP.sys and IIS) could provide a list of the trusted issuers that they supported for Client Authentication through a Certificate Trust List (CTL).
In Windows Server 2012 and Windows 8, changes were made to the underlying authentication process so that:
- CTL-based trusted issuer list management is no longer supported.
- The behavior to send the Trusted Issuer List by default is off: Default value of the SendTrustedIssuerList registry key is now 0 (off by default) instead of 1.
- Compatibility to previous versions of Windows operating systems is preserved.
But starting from windows 8 and Server 2012, the Schannel implementation will not send server side certificate trust list (CTL) by default.
Resolution:
To get this resolved we need to change the settings in the registry as described below:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL
Value name: SendTrustedIssuerList
DWORD
Set value to 1 to re-enable sending CTL behaviors.
A reboot is required as Schannel change is kernel based and has to rely on reboot taking effect.
Hope this helps....
Ashutosh Tripathi (MSFT)
Microsoft India
Comments
Anonymous
June 21, 2015
This TechNet article (technet.microsoft.com/.../hh831771.aspx) states, that "CTL-based trusted issuer list management is no longer supported". Beginning from Server 2012 there is a replacement for CTLs: "Client Authentication Issuers" certificate store.Anonymous
June 21, 2015
The comment is true .. However, with the registry changes, it can be made to manually support in 2012 or 8.1 (and above). Detailed explanation has been provided in the "Cause" section in this blog. I hope this helps.