BizTalk WCF-WebHttp adapter Client Certificate not found - ssl

When configuring the WCF-WebHttp security tab, I have set Security Mode to Transport, Client Credential type to Certificate.
When I go to browse for Client Cert, it comes up with the only options being Current User/My Store instead of Local Machine/Address Book. So, to see what happens, I imported my cert into the Current User/My Store. This worked fine and I imported the same cert into the Service Certificate tab. When a message is processed through the send port, an error like so occurs:
Cannot find the X.509 certificate using the following search criteria: StoreName 'My', StoreLocation 'CurrentUser', FindType 'FindByThumbprint', FindValue 'EF742FBAF0A13A7BEA859DC573308D52F0611CDB'.
When it tries to do a GET to the REST service we are trying to consume.
The configuration I'm using looks like so:
I'm assuming that since the BizTalk service is not running as myself, it can't find the client cert. I've also imported the cert into the Local Computer/Personal store to see if that helps, to no avail.
My question is, how can I get the correct client cert selected through the BizTalk interface? Is there a way to specify it in the Outbound Message Headers perhaps?

Certificate Usage Scenarios for the WCF Send Ports
Log on to each computer running BizTalk Server that will host the send ports as each host instance service account, and import the client certificate to the Current User \ Personal (My) store.
You can also do this by just launching the MMC as the BizTalk Service Account user.

Related

WCF: Cannot find the X.509 certificate

Error when browsing Outlook.svc from IIS.
Cannot find the X.509 certificate using the following search criteria: StoreName 'My', StoreLocation 'LocalMachine', FindType 'FindBySubjectName', FindValue ''
Because your WCF service uses a certificate to secure communication, it is usually based on the transport layer or the message layer to encrypt and sign messages.
This makes it necessary to configure a certificate for the service when hosting the WCF service in IIS.
Certificates are usually stored in the certificate Store of windows computers and are divided into current users and local machines.
You can access it using the following shell commands.
Current User Store: Certmgr.msc
Local Machine Store: Certlm.msc
https://learn.microsoft.com/en-us/windows-hardware/drivers/install/local-machine-and-current-user-certificate-stores
The error details mainly indicate that there isn’t a specific certificate that meets the search condition in the Local Machine certificate store.
To solve the problem, we could specify another certificate or change the security mode of the WCF service.
Feel free to let me know if there is anything I can help with.

BizTalk WCF-WebHttp Adapter SSL Certificate Props

What is the difference between Client Cert and Service Cert props in the security tab of WCF-BasicHttp, WCF-WebHttp adatpers based recv and send ports and how they are used by BizTalk for SSL authentication?
The documentations are not that specific.
How to Configure a WCF-WSHttp Send Port
Seems reasonably clear in that article to me
The Client Certificate is the one you hold the private key for and is used for signing your messages so the recipient can verify who you are.
certificate for authenticating this send port to services
The Service Certificate is the public key of the service you are connecting too. This way it can verify that you are connecting to who you think you are connecting too.
certificate for authenticating the service to which this send port sends messages
This is not required "The default is an empty string." however it is a security feature that prevents someone successfully being able to spoof the web service and intercepting your payload if they manage to poison the DNS entry.

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 Trasnport security with certificate client credentials using NetTcpBinding throws error on distributed system

I want to enable transport security for my Self-Hosted WCF service that uses NetTcpBinding with Certificate as client credential type. The client for this service is a WebAPI. I created certificates using makecert and everything works fine in a single PC. But when I distribute the API and the service to different PCs, I get Certificate errors like "Cannot find Server certificate in Trusted People Store" on the client side even though the certificate is present in the store.
Can someone help me where I have gone wrong?
Store your own certificate in a resources file and read that in , then set the client credential to the certificate you just read.

WCF client only works after accessing URL with IE

We have a wcf client, which calls an external webservice. The service is accessed over SSL. The certificate is not a self signed cert. It is issued by Verisign.
The client is hosted in IIS 6 and the application pool's identity is a domain service user.
Every time we want our client to access the remote service we get the following well known exception: "Could not establish trust relationship for the SSL/TLS secure channel with authority-.."
It turned out, that once you access the URL with IE on the same server, our WCF client is working as expected and the certificate is accepted!
My conclusion is, that the URL accessed with IE modified the server in a way, that our WCF client is able to do the validation afterwards. What is our WCF client missing?
(I'm aware that one can circumvent certificate validation by returning true in the ServerCertificateValidationCallback, but this is not an option for production.)
Considering the situation as described, I suspect that your IIS hosted client is not able to load the Verisign root certificate. And it is always a bit unclear to me under which account such IIS based client is trying to access the certificate store. It might be your domain service account user, it might be the ASP.NET user, it might be some other system defined account. This often causing the error.
When you browse the service with IE, there is no doubt about the user (your own credentials) being able to load the Verisign root certificate and resolve the trust relationship correctly.
Please:
Make sure the Verisign root certificate in in the Trusted Root Authorities store under the Local Computer Account
Have your app.config of your client refer to the correct root certificate to be loaded from the correct store.
You might want to run ProcessMonitor to find out which user is trying to load the certificate from the store.