Moving to a new CATO SD WAN, SSL issue with Epicor

Hello.

As the titled says, our IT is having us move to a new CATO SD WAN. But when the VPN tries to connect, it gets an SSL error. Company says it is an Epicor issue, Epicor says it is an SSL issue. What Epicor suggested did not work. Here is the error in full below. Any ideas?

pplication Error

Exception caught in: mscorlib

Error Detail 
============
Message: An error occurred while sending the request.
Inner Exception Message: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
Program: CommonLanguageRuntimeLibrary
Method: ThrowForNonSuccess

Client Stack Trace 
==================
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.<SendAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.<SendAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Ice.Cloud.ProxyBase`1.<ExecuteAsync>d__60.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Epicor.Utilities.AsyncHelper.RunSync[TResult](Func`1 method)
   at Ice.Cloud.ProxyBase`1.Execute(String methodName, RestValueSerializerBase serializer, ProxyValuesIn valuesIn, ProxyValuesOut valuesOut)
   at Ice.Cloud.ProxyBase`1.<>c__DisplayClass58_0.<CallWithCommunicationFailureRetry>b__0(Context _)
   at Polly.Policy`1.<>c__DisplayClass32_0.<Execute>b__0(Context ctx, CancellationToken ct)
   at Polly.Retry.RetryEngine.Implementation[TResult](Func`3 action, Context context, CancellationToken cancellationToken, IEnumerable`1 shouldRetryExceptionPredicates, IEnumerable`1 shouldRetryResultPredicates, Func`1 policyStateFactory)
   at Polly.RetryTResultSyntax.<>c__DisplayClass12_0`1.<WaitAndRetry>b__0(Func`3 action, Context context, CancellationToken cancellationToken)
   at Polly.Policy`1.ExecuteInternal(Func`3 action, Context context, CancellationToken cancellationToken)
   at Polly.Policy`1.Execute(Func`3 action, Context context, CancellationToken cancellationToken)
   at Polly.Policy`1.Execute(Func`2 action, Context context)
   at Ice.Cloud.ProxyBase`1.CallWithCommunicationFailureRetry(String methodName, ProxyValuesIn valuesIn, ProxyValuesOut valuesOut, RestRpcValueSerializer serializer)
   at Ice.Cloud.ProxyBase`1.CallWithMultistepBpmHandling(String methodName, ProxyValuesIn valuesIn, ProxyValuesOut valuesOut, Boolean useSparseCopy)
   at Ice.Cloud.ProxyBase`1.Call(String methodName, ProxyValuesIn valuesIn, ProxyValuesOut valuesOut, Boolean useSparseCopy)
   at Ice.Proxy.Lib.SessionModImpl.Login()
   at Ice.Core.Session.GetSessionId(String asUrl, String companyId, String plantId)
   at Ice.Core.Session.InitSessionMod(String asUrl, Boolean fwVerCheck, String companyID, String plantID, String sessionId)
   at Ice.Core.Session.InitSession(Action setCredentials, String asUrl, Guid licenseTypeId, String pathToConfigurationFile, Boolean fwVerCheck, String companyID, String plantID, Boolean useChannelCacheForServices, String sessionID)
   at Ice.Core.Session..ctor(String userID, String password, String asUrl, LicenseType licenseType, String pathToConfigurationFile, Boolean fwVerCheck, String companyID, String plantID, Boolean useChannelCacheForServices, String sessionID)
   at Ice.Core.Session..ctor(String userID, String password, LicenseType licenseType)
   at Ice.Lib.LogOn.CreateSession(String userID, String password, String appServerUri, LicenseType licenseType, SessionTokenType sessionTokenType, Object azureADOwnerWindow)
   at IceShell.Apps.LogonDialog.logOn(String userID, String password, Boolean promptUpdatePassword)
   at IceShell.Apps.LogonDialog.DoWorkLogon()

Inner Exception 
===============
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

 

   at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context)
   at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)


Inner Exception 
===============
The remote certificate is invalid according to the validation procedure.

 

   at System.Net.TlsStream.EndWrite(IAsyncResult asyncResult)
   at System.Net.PooledStream.EndWrite(IAsyncResult asyncResult)
   at System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)

Try hitting the application server itself without the Kinetic instance information on the URL. You may get a better error message.

If the error’s coming up on your side, this points at a problem with the cert on Epicor’s side…or at least that’s how it reads to me. Googled and found this on StackOverflow…maybe a clue? [Or am I clueless? :)]

1 Like

If I had to guess, Cato is doing some kind of SSL Inspection/decryption which is changing the cert from the one that the Epicor app server has, to Cato’s own one. We seen this at my organization with Cisco Umbrella, and simply had to add the url of our Epicor instance to the SSL/TLS Inspection Bypass list.

Hope this helps!

2 Likes