I am working on an M2M application where data volume is strictly limited and the mobile client has to set up at TLS connection frequently. Is there a standard way - or best practice - for the client to cache the server certificate chain such that the server does not need to send the entire chain on each connection setup?
I can think of a server that does not send along the (optional) certificate chain. The client proceeds as usual if it holds the chain in its local cache. But then, once the server certificates expire, the client must somehow tell the server that it has to send along the new chain.
Is there a possibility to configure popular TLS implementations in apache or ngix in the way described above?
Thanks very much for your help!
Uli
There is no way for the client to request the chain from the server on demand. There is a way to have a URL inside a certificate where it can get the issuers certificate, but then the client has to extract this URL and download the certificate on demand. Some desktop browsers do this, but most other SSL stacks don't.
But if client and server support session reuse, then the server has only sent the certificate and chain for the first connection in the session, but not when resuming a session.
Related
I have an app going into production. It has a java client and a java server, both of which are always the same, and under my team's control. We are using https.
Is it OK in this situation to issue a self-signed certificate and accept it on the client? Is there any risk there?
HTTTPS is to protect the connection between server and client and you don't control this connection fully just by controlling both server and client. If you accept any self-signed certificate just because you control server and client then you would also accept a certificate from a man in the middle, i.e. this would be insecure.
What you can do is to hard code the expected certificate in the client, i.e. certificate pinning. This way you only accept this specific certificate and a man in the middle attack using another certificate is not possible.
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
When the SSL certificate is revoked, some browsers (including modern ones) don't fetch the new certificate from the server, so about 0.1% of the clients are getting "Revoked certificate" error page and they can't access the service securely. The problem on the client side is solved by clearing browser's cache. However not everybody does it. Most people just close the page as fast as they can, as the error message tends to say "the authenticity of the received data could not be verified" and "report this broken site"..
Is there a way to configure HAProxy, which is working as SSL offloader in front of the web server cluster, to allow connections to be established using the "old" certificate, while all the negotiations and renegotiations are served using the "new" certificate?
P.S. This problem is partially caused by HAProxy SSL session cache, which is crucial with our load, so it can't be disabled.
The certificate of he server is sent inside each full handshake and a validation of the certificate is only done when a certificate is received and is done against the received certificate, not anything cached. But, it might happen that clients refuse to establish a connection if the fingerprint of the certificates does not match the one they've received earlier within the browser session. Or it might be, that they use implicit certificate pinning (with a browser extension), which will detect if the new certificate conflicts with an earlier received certificate and complain about it.
There is nothing you can do about it. All you get from the client at the start of the SSL handshake is the ClientHello record. This might contain the name of the target host (if SNI is used) but there is no information about any old certificates the client might have seen. This means, that the server has no information on which it could decide, if it should send the new or the older certificate for the same hostname.
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.
I know that certificates that are sent by the server cant be faked (still there is MD5 collisions but costy) but what about faking the client ..
in man in the middle attack:
cant we tell the server that we are the legitimate client and take data from that server manipulate it then encrypt it again with legitimate client public key ? how does the client be sure that the data came really from the server ?
in theory .. can we inject any data into the response sent by the server to the client ?..
How are you authenticating the client? SSL client certificates? Or some application level system (cookies etc)?
Here's what SSL does in a nutshell:
Negotiates a Diffie-Hellman shared session key between the two parties
Has the server sign the session key and send the result to the client. Once the client verifies this, the client knows there is no MITM, and the server is who they say they are.
If client certificates are enabled, has the client sign the session key and send the signature to the server. The server now knows there is no MITM and the client is who they say they are.
Encrypts all data in both directions using the shared session key
Typically when you use SSL you won't use client certificates. Strictly speaking, the server does not know if the connection is MITM'd. However, most clients will disconnect if the server certificate is bad. The server assumes that if the client pushes forward with the connection, there is no MITM. Even if Mallory, doing the MITM, chooses not to propagate the disconnect from the client, he has no new information now; all he's done is connected to the server himself. Without intercepting the client's session cookie or other authentication information (which is only sent by the client after verifying the connection is secure) the MITM is useless.
So in short, as long as one end or the other verifies the certificate of the other end before initiating any high-level communication of sensitive information, SSL is secure in both directions.
You're right -- without secure certificate authentication on the client and server there is an opening for a man in the middle attack.
SSL can be "secure both ways" if you use mutual authentication also called two-way SSL.