I'm attempting to port from 4.6.1 to ASP.NET Core 2.1.0-preview1. The following code throws an exception "Could not establish trust relationship for the SSL/TLS secure channel with authority '[service url]:447'
Am I applying the client cert incorrectly?
X509Certificate cert = X509Certificate2.CreateFromCertFile("C:\\mycert.cer");
X509Certificate2 cert2 = new X509Certificate2(cert);
var binding = new BasicHttpsBinding();
binding.Security.Mode = BasicHttpsSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var endpoint = new EndpointAddress(new Uri("https://[service url]"));
var channelFactory = new ChannelFactory<APIWebService>(binding, endpoint);
channelFactory.Credentials.ClientCertificate.Certificate = cert2;
var serviceClient = channelFactory.CreateChannel();
var result = serviceClient.getBatchesSinceGUID(new getBatchesSinceGUIDRequest("-1"));
channelFactory.Close();
FACTS
EXCEPTION STACKTRACE
System.ServiceModel.Security.SecurityNegotiationException
HResult=0x80131500
Message=Could not establish trust relationship for the SSL/TLS secure channel with authority '[server url]:447'.
Source=System.Private.ServiceModel
StackTrace:
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(HttpRequestException requestException, HttpRequestMessage request, HttpAbortReason abortReason)
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpClientRequestChannel.HttpClientChannelAsyncRequest.<SendRequestAsync>d__13.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.ServiceModel.Channels.RequestChannel.<RequestAsync>d__33.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.ServiceModel.Channels.RequestChannel.<RequestAsyncInternal>d__32.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.TaskHelpers.WaitForCompletionNoSpin[TResult](Task`1 task)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(MethodCall methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(MethodInfo targetMethod, Object[] args)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Reflection.DispatchProxyGenerator.Invoke(Object[] args)
at generatedProxy_1.getDispatchBatchesSinceUID(getDispatchBatchesSinceUIDRequest )
at NCPA.NADS.Test.UnitTest1.AdsDownload_Test() in UnitTest1.cs:line 26
Inner Exception 1:
HttpRequestException: An error occurred while sending the request.
Inner Exception 2:
WinHttpException: A security error occurred
Looks like it's probably because it's not being provided with its private key. When doing mutual certificate authentication, both parties need their public/private key pairs to establish a secure and properly authenticated channel.
In general, a .cer file typically contains only the certificate itself, which is the public key plus some metadata and the CA signature. The private key is held either in the certificate store (if it was generated/installed locally) or in a .pfx file (which will generally be either password-protected or permission-restricted).
If you do it with a .pfx file, rather than loading from the local cert store, be VERY sure that you do the following:
User contributions licensed under CC BY-SA 3.0