Use multiple SSL certificates per domain with HAProxy - ssl

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.

Related

Certificate verification when using NoVerifyHTTPAdapter

I have some code that uses Exchangelib to process emails. For various reasons, the certificate validation fails and I have to use the usual NoVerifyHTTPAdapter:
from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter
# Tell exchangelib to use this adapter class instead of the default
BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter
This leads me to two questions:
I am now wondering, am I sending and receiving in plain text without encryption? I know that the servers I am using only have port 443 open.
If I am not sending in plain text, is there a way to get the name of the certificate that I am using?
If this question is answered somewhere else, sorry for the inconvenience, it must have slipped in my initial search.
You are not sending in plain text. Your data is still encrypted since you are communicating over HTTPS.
When certificate validation fails, it means that the certificate of the server cannot be validated using any of the root certificates on your local machine that you (or your OS vendor) have chosen to trust, or that the certificate does not match the server that you are communicating with, that the certificate has expired, or any of the other reasons that may cause failure to validate a certificate.
This means that you have no guarantee that the server you are communicating with is in fact the correct server, which leaves you vulnerable to man-in-the-middle attacks and exposing your data to an untrusted server. But the communication channel itself is still encrypted.
There's some more discussion at What are the implications of ignoring SSL certificate verification?
If you absolutely cannot fix the causes of the invalid certificate, your best option is to accept the certificate locally: How to get Python requests to trust a self signed SSL certificate?

How does burp-suite intercept https requeest inspite of the encryption?

I was trying to get myself familiarised with basic concepts of https when I came across its encryption, which in a nutshell functions as follows,
Now I have seen QA engineers in my company use this tool called burp-suite to intercept request.
What I am confused about is even though the data flows through an encrypted channel, how can any interception tool like burp-suite manage to intercept the request.
Just to try it out I tried to intercept facebook request in burp-suite,
Here you can clearly see the test email test#gmail.com I used in the intercepted request.
Why is this data not encrypted according to https standards?
Or if it is then how do burp-suite manage to decrypt it?
Thank you.
Meta: this isn't really a development or programming question or problem, although Burp is sometimes used for research or debugging.
If you LOOK AT THE DOCUMENTATION on Using Burp Proxy
Burp CA certificate - Since Burp breaks TLS connections between your browser and servers, your browser will by default show a warning message if you visit an HTTPS site via Burp Proxy. This is because the browser does not recognize Burp's TLS certificate, and infers that your traffic may be being intercepted by a third-party attacker. To use Burp effectively with TLS connections, you really need to install Burp's Certificate Authority master certificate in your browser, so that it trusts the certificates generated by Burp.
and following the link provided right there
By default, when you browse an HTTPS website via Burp, the Proxy generates a TLS certificate for each host, signed by its own Certificate Authority (CA) certificate. ...
Using its own generated cert (and matching key, although the webpage doesn't talk about that because it isn't visible to people) instead of the cert from the real site allows Burp to 'terminate' the TLS session from the client, decrypting and examining the data, and then forwarding that data over a different TLS session to the real site, and vice versa on the response (unless configured to do something different like modify the data).
... This CA certificate is generated the first time Burp is run, and stored locally. To use Burp Proxy most effectively with HTTPS websites, you will need to install Burp's CA certificate as a trusted root in your browser.
This is followed by a warning about the risks, and a link to instructions to do so.
Having its own CA cert trusted in the browser means that the generated cert is accepted by the browser and everything looks mostly normal to the browser user (or other client).

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

StartSSL just for encrypted data transfer

I am developing browser extension, that sends some data from currently browsed page to my backend server. User is aware of it, it is intended.
I don't want to cause any user-data exposure, when the user is e.g. on unsecured wifi. So I just want to ensure, the data and the url goes over the net encrypted and only my backend will see them.
Do I understand correctly, that any SSL certificate, even free one from StartSSL will do the trick?
What other side effects with free SSL certificate should I consider?
- will the user's http-client trust such a certificate?
Thanks.
The SSL certificate will do the trick as long as it can be validated. That means that the root certificate of the certificate chain needs to be within the trusted certificate store of the browser.
Furthermore, the certificate will have to be for the right address (URL), must not be revoked, CRL's and OCSP must be configured correctly etc. etc. In other words, the usual steps required to have your web-service certificate validated must be met.

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.