Digital certificate in API response - ssl

I'm working on an authentication method for my NodeJS API.
I'm using TLS certificates to verify the client connected to my API server.
My question is: can we have a way to authenticate the response back to the client? Can we use cert for this to(server to client)?
eg: When we call an API from our client we send the certificate with the request which is authenticated and if found valid the server sends the response, can we do it vice-versa, send a certificate in response and have the client validate the certificate.

The whole TLS protocol and the certificates are already built around this idea that you trust the server. I.e. the server during establishing of TLS connection provides a certificate that client can verify by checking if it trusts the CA that has issued the certificate.
Now while this is generally so, you can have libraries that allows to bypass this by not checking the certificate or checking but proceeding anyway, so you have to double check that is not the case. The browser does this automatically.
If you click on a green "Secure" button that is to the left in URL in Chrome e.g. you can click on "certificate" there and see the certificate that is provided by the server. If it's green, then it's trusted and all's good.
P.S. Neither the client not server sends the certificate the whole time back and forth with each request/response. They do it only once during establishing the connection that is called TLS handshake. It's relatively expensive process so you'd better keep the connection.

Related

How to make sure Client Certificate is passed to Server

I have an application that needs to communicate with a third-party SOAP/WCF API using a client certificate. I have tried everything on the web how to call SOAP/WCF API using a client certificate. But every time I am getting a client certificate authentication failed. Is there is a way to see whether I am passing the client certificate or not? Fiddler is not showing whether the client cert is sent with the request or not.

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

Sending Client certificates in web browser

Does a web browser send client certificates to the web server on demand (means the web server is configured for client authentication and demands the client certificate) or does it just send all of the certificates that it has? If web browser sends client certificate on demand, then how does the web browser know which client certificate to sent to that particular web server?
I put my question on https://security.stackexchange.com/ and got this answer from #gowenfawr:
During the SSL handshake,
If the server requires a digital certificate for client authentication,
the server sends a "client certificate request" that includes a list of
the types of certificates supported and the Distinguished Names of
acceptable Certification Authorities (CAs).
(quote is from a reasonably lucid explanation of the SSL handshake by
IBM.)
The client then compares the certificates in its store against that
list to see if it has any signed by the CAs that the server listed. If
it finds one, it will send it, usually after prompting the user
whether they want to send it. Presumably if there were multiple
matches it would ask the user which to send (if any).

Verify what client authentication certificates are sent to server?

Is there a way in browser or through some tool to see what SSL certificate (client authentication) was sent to server in request?
I'd start with something like Burp Suite (Free Edition). It's a darn good proxy for... lots of things.
If your server negotiates the client certificate during the initial handshake (without renegotiation), you should be able to see it using Wireshark: you should see a Certificate message coming from the client (not the one coming from the server), after a Certificate Request message sent by the server.
If renegotiation is used, this is more complicated.
SSL MITM tools (like Fiddler) won't be of any help, since they perform their own handshakes. Such tools can be configured to fool the client into believing they are the real server, by having the client trust their fake server certificate (a trust setting the user can generally set on the client). However, this doesn't work on when using a client certificate, unless the tool performing the handshake (the SSL MITM tool in this case) was handling the client certificate itself. Otherwise the verification message at the end (which the server uses to verify that the client has the private key for the client certificate) would fail. Some of these tools can indeed be configured with a client certificate, but you need to set them up with the corresponding private key: in this case you would know which client certificate was used.
Another way to check would be to check what the browser itself does. How to do it may depend on the browser. Environment variables like SSLDEBUG might be of interest when using Firefox.

Two-way SSL clarification

I am somewhat confused as to how two-way SSL works. How does the client create its certificate to send to the server? Is it generated from the server and distributed to the client?
Also, what is the advantage of two-way SSL over one-way SSL?
Both certificates should exist prior to the connection. They're usually created by Certification Authorities (not necessarily the same). (There are alternative cases where verification can be done differently, but some verification will need to be made.)
The server certificate should be created by a CA that the client trusts (and following the naming conventions defined in RFC 6125).
The client certificate should be created by a CA that the server trusts.
It's up to each party to choose what it trusts.
There are online CA tools that will allow you to apply for a certificate within your browser and get it installed there once the CA has issued it. They need not be on the server that requests client-certificate authentication.
The certificate distribution and trust management is the role of the Public Key Infrastructure (PKI), implemented via the CAs. The SSL/TLS client and servers and then merely users of that PKI.
When the client connects to a server that requests client-certificate authentication, the server sends a list of CAs it's willing to accept as part of the client-certificate request. The client is then able to send its client certificate, if it wishes to and a suitable one is available.
The main advantages of client-certificate authentication are:
The private information (the private key) is never sent to the server. The client doesn't let its secret out at all during the authentication.
A server that doesn't know a user with that certificate can still authenticate that user, provided it trusts the CA that issued the certificate (and that the certificate is valid). This is very similar to the way passports are used: you may have never met a person showing you a passport, but because you trust the issuing authority, you're able to link the identity to the person.
You may be interested in Advantages of client certificates for client authentication? (on Security.SE).
What you call "Two-Way SSL" is usually called TLS/SSL with client certificate authentication.
In a "normal" TLS connection to example.com only the client verifies that it is indeed communicating with the server for example.com. The server doesn't know who the client is. If the server wants to authenticate the client the usual thing is to use passwords, so a client needs to send a user name and password to the server, but this happens inside the TLS connection as part of an inner protocol (e.g. HTTP) it's not part of the TLS protocol itself. The disadvantage is that you need a separate password for every site because you send the password to the server. So if you use the same password on for example PayPal and MyPonyForum then every time you log into MyPonyForum you send this password to the server of MyPonyForum so the operator of this server could intercept it and try it on PayPal and can issue payments in your name.
Client certificate authentication offers another way to authenticate the client in a TLS connection. In contrast to password login, client certificate authentication is specified as part of the TLS protocol. It works analogous to the way the client authenticates the server: The client generates a public private key pair and submits the public key to a trusted CA for signing. The CA returns a client certificate that can be used to authenticate the client. The client can now use the same certificate to authenticate to different servers (i.e. you could use the same certificate for PayPal and MyPonyForum without risking that it can be abused). The way it works is that after the server has sent its certificate it asks the client to provide a certificate too. Then some public key magic happens (if you want to know the details read RFC 5246) and now the client knows it communicates with the right server, the server knows it communicates with the right client and both have some common key material to encrypt and verify the connection.
In two way ssl the client asks for servers digital certificate and server ask for the same from the client. It is more secured as it is both ways, although its bit slow. Generally we dont follow it as the server doesnt care about the identity of the client, but a client needs to make sure about the integrity of server it is connecting to.