WCF Service Could not establish trust relationship for the SSL/TLS secure channel with authority - wcf

I have my WCF service running in HTTP. I want to make my service run in HTTPS. I did this in my local with self seigned certificate and its working fine. But I'm getting
"Could not establish trust relationship for the SSL/TLS secure channel with authority"
error when I deployed my code in QA environment and created Self signed certificate for the same. I found some solution to validate the certificate at client side (Link). But I'm looking for some solution to fix this from server side. I don't want to disturb the client.

I suspect the error reflect that the client does not recognize your self-signed certificate or the underlying certificate authority. As such, until the client adds the client certificate to their certificate store or otherwise trusts the certificate, the only way they will be able to access the service is via a validation workaround like the one reflected in the link you included.
In order to determine the underlying cause of the issue, you may want to enable WCF Tracing and review the exceptions (especially inner exceptions).
My team supports many WCF connections protected by mutual certificate authentication. We have noticed that the error top level error may not provide as much information as the inner exception. Just yesterday, I had a site with that exact error. When we looked in the trace file, we saw an inner exception revealing that the certificate had not been deployed to the certificate store in the proper location. A few days previously, the “could not establish trust relationship” error had an underlying inner exception that revealed the certificate had been revoked by the certificate authority.
Hope this helps.
Regards,

Related

HTTPS communication in ServiceFabric Local Cluster

Here's my setup
an IdentityServer 4 as a stateless reliable ASP.NET Core service.
a WebAPI as a reliable ASP.NET Core service.
using them with a JS client, it is now working with HTTP. The problem is with HTTPS. The WebAPI needs to request the openID config via htttps [is4URL].well-known/openid-configuration. I'm getting this error
System.InvalidOperationException: IDX10803: Unable to obtain
configuration from:
'https://localhost:9999/.well-known/openid-configuration'. --->
System.IO.IOException: IDX10804: Unable to retrieve document from:
'https://localhost:9999/.well-known/openid-configuration'. --->
System.Net.Http.HttpRequestException: An error occurred while sending
the request. ---> System.Net.WebException: The underlying connection
was closed: Could not establish trust relationship for the SSL/TLS
secure channel. --->
System.Security.Authentication.AuthenticationException: The remote
certificate is invalid according to the validation procedure.
can anybody help me to make this work in localhost with the SF Local Cluster Manager?
Thanks
Here's my two cents worth but it will need to be verified...
I am assuming that you have created a self-signed certificate using following article or similar but the certificate has same properties.
https://learn.microsoft.com/en-us/azure/app-service-web/web-sites-configure-ssl-certificate
This means that the certificate can not be verified via actual CA. Ofcourse with self-signed certificate this is not possible.
Now when you upload the certificate to Azure App Service it installs in CurrentUser - MyStore. With self-signed certificate, it also needs to be installed in LocalMachine Root store.
This is becouse then the machine's Certificate Authority can verify that certificate to be valid. (May be a security expert can correct me if I am wrong but thats my theory). I have got same setup on my locally hosted windows server where the self-signed certificate is installed in Root Certificate Store as well as Personal store and the app works. This is the reason I belive this happens.
So this part which needs to be verified. Following is the article which shows you how you can do this in Azure App service.
https://learn.microsoft.com/en-us/azure/cloud-services/cloud-services-configure-ssl-certificate-portal
AGAIN THIS IS JUST A THEORY THIS NEEDS TO BE VERIFIED. :)
EDIT:
I have just tested this and it is the case. In cloud services you can do as shown in second link above and create Web Job which install certificate in appropriate store.
For Azure App Service unfortunaltly you dont have access to root store. It has to be install in CurrentUser's personal store. Which means the self signed certificate will not work, and you have to purchase a real certificate. :( I think this is a real thumb down to Microsoft. Why should I need to pay for real certificate for my dev/test environment? (Rant Over)
For Service Fabric you will need to find out how to install certificate in Root Store as well as personal store (if thats possible at all). Here's Links that might be useful
http://ronaldwildenberg.com/running-an-azure-service-fabric-cluster-locally-on-ssl/
https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-cluster-security-update-certs-azure
Hope this helps.

Self signed client certificate does not reach server application

I have the following setup:
A self signed certificate for development purposes
An OWIN hosted Web API, deployed on a local Azure Service Fabric Cluster as a ASF service. The Web API uses HTTPS facilitated with the dev certificate in question.
A simple .net client application that calls the Web API. In that application the ServicePointManager.ServerCertificateValidationCallback method is set so it always returns true (since the CA is not trusted)
Both the client application and the Web API are on the same local development machine. The certificate is installed in that same machine on the "machine store"
Now I am able to make calls to the web api using Fiddler by providing the required client certificate. However when I try to do the same via .net code (be it RestSharp or WebRequest) the client certificate is not present in the RequestContext object on the server side. This result in an Unauthorized response. I do not think the problem is with the client code, the certificate is loaded correctly and assigned to the http client or request. Fiddler shows encrypted tunneling to the server. However the client certificate does not seem to be present at the server side.
I am at a complete loss regarding what am I missing that could cause this behavior. Any help will be deeply appreciated.
Install the certificate into the 'Local Machine/Trusted People'.
The server needs to already trust the certificate before it asks. The CertificateRequest message that it sends lists the acceptable CAs that can sign the client certificate. If the client certificate's signer isn't in that message, it can't send it.
How you accomplish that in your environment is left as an exercise for the reader. In general now that SSL certificates are available free there is little reason to indulge in the time costs and administrative inconveniences of self-signed certificates. IMHO there wasn't even if you were paying for a CA signature.
I had a problem when a service called another service over HTTPS and it couldn't setup a secure connection. My problem was that since the service is running as NETWORK SERVICE, it couldn't find the certificate, because it was looking in the localmachine/my certificate store.
When I was running from my web browser it was working fine because then, my browser found the certificate in the currectuser/my certificate store.
Add the certificate to the machine/my store and see if it helps.

2 Way SSL - Client Certificate Not Sent To Server

I'm have an application deployed to salesforce on the force.com platform,
which I'm trying to configure a 2 way SSL for.
I.e.
I want that for each request sent to from SF to my server, a client certificate will be sent.
I did the necessary configurations on SF for the certificate to be sent, but I'm still getting 403.7 from the server, which means: forbidden, client certificate required.
I installed wireshark on the server, captured traffic to see the 2 way ssl handshake, and I'm trying to find in the server hello message where it tells the client the trusted CAs from which a client certificate should correspond, but I'm having difficulties finding it.
I suspect that's why the client does not send the certificate.
Can anyone point me to where in the server hello I should look? Or perhaps in another packet capture?
Thanks in advance.
Client Key Exchange record:
Here, the server sends its Certificate Request message and the client sends its Certificate message in response, but that message contains 0 certificates.
Typically, this happens when the client was unable to select a client certificate to use. Either it's not configured properly to make use of any certificate, or it can't find one that is issued by one of the acceptable CAs.
Look at the Certificate Request packet and check its certificate_authorities list. This is a list of the CA Distinguished Names (DNs) that the server is willing to accept.
One way or another, the client will need to find a client certificate with which it can build a chain towards of those DNs. In the simplest case, a client certificate issued by such a DN is available. Otherwise, the client could have to build a chain from a client cert to such a DN, it would need to have the necessary intermediate CA certificates to do so. (How this is done depends on the client's configuration mechanisms.)
If intermediate CA certificates are necessary and not available on the client side, you may need to configure your server to accept them and advertise them in the Certificate Request too.
Added a screenshot of the handshake captures. can you please point me to where I should be looking? –
See packet #31. It contains the Certificate Request. Also packet #33 contains the certificate from the client, so the reason is not the client does not send the certificate, but instead that the server either does not like the certificate because the validation failed or because the certificate is not sufficient as authorization for the requested resource. You might get more information from the servers log.
Not sure if this will help anyone else, but for our case of this issue everything was working when running locally in Visual Studio and in IIS, but when deployed to a real server, we were hitting a certificate issue during 2-way SSL as described above and verified in Wireshark.
Anyway, on that server we have also have a .NET 4.7.2 Console application which was calling the same API and everything was working fine.
But, our .NET 4.7.2 web API calls were failing. It appears that when the same code was running inside IIS the cert was not available during the SSL negotiation. (although it loaded fine)
Our solution at this point was to modify the following call to include the 3rd parameter.
certificate = new X509Certificate2(certificatepath, Password, X509KeyStorageFlags.MachineKeySet);
By default X509Certificate2 uses the UserKeySet option, so perhaps the application pool user or another thread in IIS (?) was having trouble accessing the cert for the negotiation.
Here are a couple of the related pages that I found useful during my research:
https://paulstovell.com/x509certificate2/
https://github.com/dotnet/runtime/issues/23437

WCF - Is a service certificate needed to authenticate clients?

I think there's a gap in my mental model of WCF authentication, hoping someone can help me fill it in.
So, I'm creating a WCF service and would like to have clients authenticate using certificates, and message-level security. I'd like the service to validate these using chain trust so that I don't need each client cert installed on the service. For now, I'm not interested in having the service authenticate to the client.
Here's my understanding of what's needed to do this:
The client needs a certificate signed by a CA that's trusted on the service side.
The service needs a CRL installed for that CA.
The service config should have message security turned on, specify clientCredentialType="Certificate", and chain trust for client certificate validation.
The client config should have message security turned on, specify clientCredentialType="Certificate", and an endpoint behavior that tells how to find the client certificate in the store.
The client makes a request to the service, sending its certificate. The service sees that the client's cert is signed by its trusted CA and lets the request through.
Now, all of the walkthroughs of this process I've found also include a step of creating a certificate for the service. None of them explain what this is for, which is throwing me. Why is a service certificate needed if I just want to authenticate the clients?
You are right. In theory no server certificate is required, in practice wcf enforce you to use one. The good news is that you should use a dummy certificate for the server and also set ProtectionLevel to SignOnly. I suggest to read this article which talks on a similar scenario and mostly relevant.

SSL XML Gateway - SSL Certificate Handshake Error

I am working on a website that exposes an xml gateway that clients can submit an xml request to and get an xml response in return. The website/company has been purchased by a larger organization and has been migrated into their infrastructure. The existing production site is using an ssl certificate by a particular certificate authority but the larger organization uses certificates issued by a different certificate authority. We have tried run a test with one of their clients and they are getting an SSL handshake error. The original developer says that the only way to get it to work is to restore the original SSL certificate and not to use the new ones. I am looking for some guidance or direction to diagnose this issue, so any help would be appreciated.
What the developer says, from the description is sensible to me, but the problem is theirs.
To verify that this is exactly what is happening you can do a wireshark capture and then decode the flow as SSL. If the problem is that the client do not trust the certificate send by the server and reject the connection you will see it in the handshake in the wireshark.
If you use a java client you could run it with -Djavax.net.debug=ssl to see the ssl messages from within java.
If this is indeed the problem then you must configure the client's truststore to have the certificate send by the server (which is the original one).
If this configuration is possible of course... This depends on the application
UPDATE:
Well if you migrated to a new CA, i.e. you deploy a new certificate in your interface, then sorry to say, it is "your" -meaning the server side- error.
IMHO, if it is possible, you should redeploy the old certificate for a prespecified period, communicating to all the stakeholders that you plan to migrate to a new certificate signed by a new CA, so that the clients don't break
Then it is their responsibility, within that period, to "fix" their client apps to be able to accept the new certificate. This can be as simple as configuration i.e. importing the certificate to a truststore, to as "complicated" as to change code and rebuild the client app (e.g. if the new issued certificate does not have extensions that the code is verifying or the CN has changed etc).
If it is not possible to redeploy the old certificate then, you just have to communicate the change to all stakeholders and then, they should "fix" it accordingly (as mentioned above)