WCF net tcp with certifcate , connection client-server failed
Service :
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
Service Code:
Uri baseAddress = new Uri("net.tcp://localhost:8632/TestService");
ServiceHost host = new ServiceHost(typeof(ReconCommService.ReconstructionService),new Uri[] { baseAddress } );
host.Credentials.ServiceCertificate.Certificate = CertificateManager.VeritonCertificate.CertifciateOf.ServerCert();
host.Open(); //Open successfully
public X509Certificate2 ServerCert()
{
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
//var store = new X509Store("SDM.Veriton", StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates;
var cn = "CN=Server.Veriton.local, O=Spectrum Dynamics Medical Ltd, OU=\"\", S=\"\", L=\"\", C=\"\"";
var currentCerts = certCollection.Find(X509FindType.FindBySubjectDistinguishedName, cn, false);
return currentCerts.Count == 0 ? null : currentCerts[0];
}
Client:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBindingEndpoint">
<reliableSession inactivityTimeout="05:00:00" enabled="true" />
<security mode="Message">
<!--<transport sslProtocols="None" />-->
<message clientCredentialType="Certificate" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:8632/TestService"
binding="netTcpBinding" bindingConfiguration="NetTcpBindingEndpoint"
contract="ReconServiceRef.IReconstructionService" name="NetTcpBindingEndpoint">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
Client Code:
binding = new NetTcpBinding();
binding.Name = "NetTcpBindingEndpoint";
binding.MaxBufferSize = int.MaxValue;
binding.MaxReceivedMessageSize = int.MaxValue;
binding.ReceiveTimeout = new TimeSpan(5, 0, 0);
binding.OpenTimeout = new TimeSpan(0, 0, 10);
binding.SendTimeout = connectionTimeout;
binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
binding.ReaderQuotas.MaxDepth = int.MaxValue;
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
binding.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
binding.ReaderQuotas.MaxNameTableCharCount = int.MaxValue;
binding.ReliableSession.InactivityTimeout = inactivityTimeout;
binding.ReliableSession.Enabled = true;
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
string uriStr = "net.tcp://127.0.0.1:8632/TestService";
endpointAddress = new EndpointAddress(uriStr);
ctx = new InstanceContext(callbackInstance);
factory = new DuplexChannelFactory<IReconstructionService>(ctx, binding, endpointAddress);
factory.Credentials.ClientCertificate.Certificate = CertificateManager.VeritonCertificate.CertifciateOf.ClientCert();
public X509Certificate2 ClientCert()
{
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
//var store = new X509Store("SDM.Veriton", StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates;
var cn = "CN=Client.Veriton.local, O=Spectrum Dynamics Medical Ltd, OU=\"\", S=\"\", L=\"\", C=\"\"";
var currentCerts = certCollection.Find(X509FindType.FindBySubjectDistinguishedName, cn, false);
return currentCerts.Count == 0 ? null : currentCerts[0];
}
public IReconstructionService CLientProxy
{
get
{
if (System.Net.ServicePointManager.SecurityProtocol == (SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
// --- This is a workaround for reducing the connection timeouts without touching the sendTimeout
IReconstructionService channel = factory.CreateChannel();
var ar = ((IChannel)channel).BeginOpen(null, null);
if (!ar.AsyncWaitHandle.WaitOne(factory.Endpoint.Binding.OpenTimeout, true))
{
throw new TimeoutException("Service is not available");
}
((IChannel)channel).EndOpen(ar); // <<-- Where the exception occurs
myChannel = channel;
return channel;
// ---- If it's making any problems --> comment this code and return above 2 commented lines
}
}
Exception Message : The caller was not authenticated by the service.
From WCF Log :
The X.509 certificate CN=Client.Veriton.local, O=Spectrum Dynamics Medical Ltd, OU="", S="", L="", C=""; 7C02D26E1C59558A51C3CDC02CB36C280E50BA24 chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. The revocation function was unable to check revocation for the certificate.