title: WCF SslStreamSecurity DNS Identity Check failing for just 4.6 framework
body: <p>I am working on developing a new binding for a Wcf service that is hosted in IIS, I thought I got everything working, but it turns out that the client only works when it is targetting .Net framework 4.5, if I change it to target 4.6 then I get the following error when I try to open a connection:</p>
  
  <pre><code>System.ServiceModel.Security.MessageSecurityException occurred
    HResult=-2146233087
    Message=The Identity check failed for the outgoing message. The remote endpoint did not provide a domain name system (DNS) claim and therefore did not satisfied DNS identity 'xxx.domain.local'. This may be caused by lack of DNS or CN name in the remote endpoint X.509 certificate's distinguished name.
    Source=System.ServiceModel
    StackTrace:
         at System.ServiceModel.Security.IdentityVerifier.EnsureIdentity(EndpointAddress serviceReference, AuthorizationContext authorizationContext, String errorString)
  </code></pre>
  
  <p>If I do nothing other than change the target framework in my test code back to 4.5, then it works fine. This makes me think that it could be a bug in .Net 4.6, I know there were <a href="https://msdn.microsoft.com/en-us/library/ms171868(v=vs.110).aspx#v46" rel="noreferrer">Wcf ssl changes made in 4.6</a></p>
  
  <p>With first chance exceptions turned on I see the following exception that is raised internally in System.ServiceModel</p>
  
  <pre><code>System.ArgumentNullException occurred
    HResult=-2147467261
    Message=Value cannot be null.
  Parameter name: value
    ParamName=value
    Source=mscorlib
    StackTrace:
         at System.Enum.TryParseEnum(Type enumType, String value, Boolean ignoreCase, EnumResult&amp; parseResult)
    InnerException: 
  
      System.ServiceModel.dll!System.ServiceModel.Security.IssuanceTokenProviderBase&lt;System.ServiceModel.Security.Tokens.IssuedSecurityTokenProvider.FederatedTokenProviderState&gt;.DoNegotiation(System.TimeSpan timeout)  Unknown     System.ServiceModel.dll!System.ServiceModel.Security.IssuanceTokenProviderBase&lt;System.ServiceModel.Security.Tokens.IssuedSecurityTokenProvider.FederatedTokenProviderState&gt;.GetTokenCore(System.TimeSpan timeout)   Unknown
      System.IdentityModel.dll!System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(System.TimeSpan timeout) Unknown
      System.ServiceModel.dll!System.ServiceModel.Security.Tokens.IssuedSecurityTokenProvider.GetTokenCore(System.TimeSpan timeout)   Unknown
      System.IdentityModel.dll!System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(System.TimeSpan timeout) Unknown
      System.ServiceModel.dll!System.ServiceModel.Security.SecurityProtocol.TryGetSupportingTokens(System.ServiceModel.Security.SecurityProtocolFactory factory, System.ServiceModel.EndpointAddress target, System.Uri via, System.ServiceModel.Channels.Message message, System.TimeSpan timeout, bool isBlockingCall, out System.Collections.Generic.IList&lt;System.ServiceModel.Security.SupportingTokenSpecification&gt; supportingTokens)    Unknown
      System.ServiceModel.dll!System.ServiceModel.Security.TransportSecurityProtocol.SecureOutgoingMessageAtInitiator(ref System.ServiceModel.Channels.Message message, string actor, System.TimeSpan timeout)    Unknown
      System.ServiceModel.dll!System.ServiceModel.Security.TransportSecurityProtocol.SecureOutgoingMessage(ref System.ServiceModel.Channels.Message message, System.TimeSpan timeout) Unknown
      System.ServiceModel.dll!System.ServiceModel.Security.SecurityProtocol.SecureOutgoingMessage(ref System.ServiceModel.Channels.Message message, System.TimeSpan timeout, System.ServiceModel.Security.SecurityProtocolCorrelationState correlationState)  Unknown
      System.ServiceModel.dll!System.ServiceModel.Channels.SecurityChannelFactory&lt;System.ServiceModel.Channels.IRequestChannel&gt;.SecurityRequestChannel.Request(System.ServiceModel.Channels.Message message, System.TimeSpan timeout) Unknown
      System.ServiceModel.dll!System.ServiceModel.Channels.TransactionRequestChannelGeneric&lt;System.ServiceModel.Channels.IRequestChannel&gt;.Request(System.ServiceModel.Channels.Message message, System.TimeSpan timeout)  Unknown
      System.ServiceModel.dll!System.ServiceModel.Dispatcher.RequestChannelBinder.Request(System.ServiceModel.Channels.Message message, System.TimeSpan timeout)  Unknown
      System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.Call(string action, bool oneway, System.ServiceModel.Dispatcher.ProxyOperationRuntime operation, object[] ins, object[] outs, System.TimeSpan timeout)  Unknown
      System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(System.Runtime.Remoting.Messaging.IMethodCallMessage methodCall, System.ServiceModel.Dispatcher.ProxyOperationRuntime operation) Unknown
      System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannelProxy.Invoke(System.Runtime.Remoting.Messaging.IMessage message) Unknown
      mscorlib.dll!System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(ref System.Runtime.Remoting.Proxies.MessageData msgData, int type) Unknown
  </code></pre>
  
  <p>The wcf service being communicated to is targeting 4.6, and as far as I can tell I am specifying the dns identity, which does exist as a CN= in the cert subject. The binding is a custom binding so that I can do federated net.tcp, the client creates everything in code and I don't use the Add Service Reference feature in visual studio, the client code that is creating the binding:</p>
  
  <pre><code>var binding = new CustomBinding(new BindingElement[] {
              new TransactionFlowBindingElement(),
              security,
              new SslStreamSecurityBindingElement(),
              new BinaryMessageEncodingBindingElement() {
                  ReaderQuotas = { MaxDepth = maxReceivedSizeBytes, MaxStringContentLength = maxReceivedSizeBytes, MaxArrayLength = maxReceivedSizeBytes, MaxBytesPerRead = maxReceivedSizeBytes, MaxNameTableCharCount = maxReceivedSizeBytes },
              },
              new TcpTransportBindingElement {
                  TransferMode = TransferMode.StreamedResponse,
                  MaxReceivedMessageSize = maxReceivedSizeBytes,
              },
          }) {
      SendTimeout = sendTimeout,
  };
  
  var channelFactory = new ChannelFactory&lt;T&gt;(binding, new EndpointAddress(new Uri(url), EndpointIdentity.CreateDnsIdentity("xxx.domain.local"), new AddressHeader[0]));
  </code></pre>
  
  <p>Could this be a bug in the 4.6 framework causing different behavior? Would the next steps only be trying to step through and debug framework code to try and find why 4.6 is behaving differently?</p>
  
  <p><strong>EDIT -</strong> 
  I created a <a href="https://github.com/brandonagr/Wcf46IdentityFailExample" rel="noreferrer">small sample project that demonstrates the error</a>, the repro steps are:</p>
  
  <ul>
  <li>(Using VS 2015) Open the WcfSelfHostedServer solution</li>
  <li>Add the IdentityFail.pfx cert to your Local Computer, Personal store using mmc</li>
  <li>Run the WcfSelfHostedServer project (likely clicking firewall yes allow port 30000)</li>
  <li>Open the WcfClient solution</li>
  <li>Right click on project > properties, note that it is targetting 4.6.1</li>
  <li>Run the project, it will throw the exception described above</li>
  <li>Now switch the client to target 4.5.2, it will run fine with no errors</li>
  </ul>
  
  <p><strong>Update -</strong>
  I found the following that appear related:
  <a href="https://support.microsoft.com/en-us/kb/3069494" rel="noreferrer">https://support.microsoft.com/en-us/kb/3069494</a>
  <a href="https://msdn.microsoft.com/en-us/library/mt298998(v=vs.110).aspx" rel="noreferrer">https://msdn.microsoft.com/en-us/library/mt298998(v=vs.110).aspx</a></p>
  
  <p>But specifying Tls12 at the server and client didn't fix the issue, and even adding the DontEnableSchUseStrongCrypto=true flag didn't affect the DNS Identity Check error even though it got around the Enum.Parse internal error that <a href="http://referencesource.microsoft.com/#System/net/System/Net/ServicePointManager.cs,686" rel="noreferrer">was being thrown from this line</a></p>