I have a WCF client (.NET 4.0) that calls goverment medical service over SOAP/SSL. It works for a first couple of hours and make a dozen or more successfull calls to service , and then it brekas with exception. After first exception WCF calls will not work until application is restarted.
It works at other instalations , and event works at same place but only if run od Win 10 PC, but it must work on server. The server in question is Windows 2012 with latest updates.
The exception is :
SecurityNegotiationException: Could not establish secure channel for SSL/TLS with authority 'ws.cezih.hr:6443'.
INNER EXCEPTION MESSAGE :WebException: The request was aborted: Could not create SSL/TLS secure channel.
which is caused by :
AuthenticationException: A call to SSPI failed, see inner exception.
INNER EXCEPTION MESSAGE :Win32Exception: The Local Security Authority cannot be contacted
I looked at event log to search for SChanell errors but there are none. Then I found that it is possible to change logging level for SChanell : http://www.infralib.com/2016/11/schannel-event-logging-levels/
After that there are many many logs for SCHanell in event log (20 per sec), and this happens in same time with error in app but I can not guarantee because there are lots of them :
A fatal alert was generated and sent to the remote endpoint. This may
result in termination of the connection. The TLS protocol defined
fatal error code is 80. The Windows SChannel error state is 301.
There is nothing on Google for this particular error codes.
Because I can't test by myself (need smart card certificate from nurse), an it happens after 2-3 hours of usage I didt get a chance to get a Wireshark trace yet.
UPDATE 12.6.2020 after aplying suggestion :::::::::::::::::::::::::
This was my config :
<basicHttpBinding>
<binding name="osiginfo">
<security mode="Transport">
<transport clientCredentialType="Certificate"></transport>
</security>
</binding>
</basicHttpBinding>
I make it an wsHttpBinding with reliableSession as suggested :
<wsHttpBinding>
<binding name="osiginfo" receiveTimeout="24:00:00">
<security mode="Transport">
<transport clientCredentialType="Certificate"></transport>
</security>
<reliableSession enabled="true" inactivityTimeout="24:00:00"/>
</binding>
</wsHttpBinding>
With this config I get exception : Binding validation failed because the WSHttpBinding does not support reliable sessions over transport security (HTTPS). The channel factory or service host could not be opened. Use message security for secure reliable messaging over HTTP.
I found what it is about here : How to enable Session with SSL wsHttpBinding in WCF
And made only possible solution from there , a change in security mode :
<wsHttpBinding>
<binding name="osiginfo" receiveTimeout="24:00:00">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Certificate"></transport>
</security>
<reliableSession enabled="true" inactivityTimeout="24:00:00"/>
</binding>
</wsHttpBinding>
And with this config I get : AuthenticationException: A call to SSPI failed, see inner exception. INNER EXCEPTION MESSAGE :Win32Exception: The message received was unexpected or badly formatted (Probably because it expects credentials in returning message.)
Which of course ends with : SecurityNegotiationException: Could not establish secure channel for SSL/TLS with authority 'ws.cezih.hr:6443'. INNER MESSAGE :WebException: The request was aborted: Could not create SSL/TLS secure channel.
I do not have control over service implementation (it is healthcare/goverment).
Is there any other way to stop expire of channel ?
I will mention again that this works on other instaltions/servers at other clients, it is something with this particular server or OS/.NET/update combination.
Is there any way of getting what is wrong wtih SChanel ?
Error 80 means "INTERNAL ERROR" for SChanell and that is only stuff you can google out.
UPDATE 19.6.2020 :::::::::::::::::
try {
CezihOsigInfo.osigInfoForBISResponseOsigInfoForBISOutput[] response = null;
using (CezihOsigInfo.osiginfoPortTypeClient client = new CezihOsigInfo.osiginfoPortTypeClient())
{
client.ClientCredentials.ClientCertificate.Certificate = DohvatiKlijentskiCertifikat();
base.PostaviDodatnePodatkeCertifikata(client?.ClientCredentials?.ClientCertificate?.Certificate);
try
{
base.ZapisiSlanje(string.Format("Dohvat informacija o osiguranju pacijenta: {0}", mbo), "DohvatiOsiguranikaPrekoMBO");
response = client.osigInfoForBIS(mbo);
base.ZapisiPrimanje(string.Format("Dohvaćeni podaci o osiguranju pacijenta: {0}", mbo), StatusPrijenosa.DohvatiPrekoPK(100));
base.ZapisiLog();
}
catch (System.ServiceModel.Security.SecurityNegotiationException ex)
{
//try one more call
using (CezihOsigInfo.osiginfoPortTypeClient client2 = new CezihOsigInfo.osiginfoPortTypeClient())
{
client2.ClientCredentials.ClientCertificate.Certificate = DohvatiKlijentskiCertifikat();
try
{
base.ZapisiSlanje(string.Format("Dohvat informacija o osiguranju pacijenta DRUGI POKUSAJ: {0}", mbo), "DohvatiOsiguranikaPrekoMBO");
response = client2.osigInfoForBIS(mbo);
base.ZapisiPrimanje(string.Format("Dohvaćeni podaci o osiguranju pacijenta DRUGI POKUSAJ: {0}", mbo), StatusPrijenosa.DohvatiPrekoPK(100));
base.ZapisiLog();
}
catch {
base.ZapisiPrimanje(string.Format("Greška prilikom dohvata informacija o osiguranjima pacijenta DRUGI POKUSAJ: {0}", mbo), StatusPrijenosa.DohvatiPrekoPK(1));
base.ZapisiLog();
throw new ObavijesnaIznimka("Dogodila se greška prilikom poziva servisa (DRUGI POKUSAJ). " + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
}
}
}
catch (Exception ex)
{ ........
I added another call with another newly created client , and I get the same error. I wonder what is there in some GLOBAL state about SSL that it requires restart of application, everithing is recreatdd for second call, does WCF framework reuses channels in background or something similar ?