So, for an assignment I need to use GnuTLS and to start of, I followed the client and server examples in the documentation (http://www.gnutls.org/manual/gnutls.html) (client and server examples with X.509). Everything works fine till there.
However, I would like the server to authenticate the client (which, in the examples, does not by default). A little research has lead me to changing the flag GNUTLS_CERT in:
gnutls_certificate_server_set_request (mSession, GNUTLS_CERT_REQUEST);
I understand that this returns an error if the client does not provide a certificate that matches the server's trusted CA. However, is this enough to authenticate the client, or should there be more steps for authentication?
Thanks in advance.
Related
I am running a small sinatra application which re-uses a company-wide client certificate every employee has already installed (signed by an internal SSO_CA).
My Sinatra/Thin combination is using the server certificate signed by an internal company CA but is expecting the client certificate signed by SSO_CA.
Technically this worked fine until we got a second self-signed client certificate on our PCs. The browser is unsure which certificate to use and is guessing the wrong one, most users do not read and use the new certificate, which ends in a 403 error.
In addition, browsers remember the decision and you have to explain to many people how to reset the SSL state.
=> Sinatra / Thin/ Eventmachine are not providing an option like :SSLCACertificateFiles '/usr/sinatra/certs/SSO_CA.crt'
to tell the browser "please show up with client certificate from SSO_CA"
Webrick has it but this is not the right choice for "production". Moving to Nginx feels strange as I cannot be the first having this issue in Thin.
I remember there was somewhere in a forum (cannot find it again) someone telling me that the feature is missing but I found this before I had an understanding that this is going to be my problem as well.
Has anybody an idea how to force Thin/Eventmachine to forward a specific CA suggestion for client certificate? It is not :SSLCACertificateFiles, I tried it already.
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
I'm a little bit confused about what the client certificates all about.
I have set to "IGNORE" the client certificates on my SSL Settings. But i'm worrying if its ok or not. Can someone explain to me the difference or importance/advantages of those three.
and Which one is most used/advisable?
Thanks
Client certificates are used for client side authentication of an SSL connection.
Usually the default is to not request a client certificate since a server may server thousands of clients and the only way to be able to do client authentication (and would make sense) is for the server and clients to be part of the same PKI infrastructure (which practically means part of the same organization).
So unless you are asking about your browser it is ok. There is no vulnerability to fear on your side. The worse thing that could happen is that you would not be able to connect to sites that actually do client authentication
The ColdFusion documentation is weak on how and when to use it. What does it do? How does one use it?
Update: it seems to be broken, as outlined in Washing Client Certs in ColdFusion with SOAP – Part 2.
problems with CFHTTP handling SSLv3 sessions
Client certificates are a bit of a pain because of the overhead involved in using it.
As Jura says, you'll need a target server that uses client certificates as a mechanism for authentication. This server side piece does not need to be CF-based. The web server (IIS, for example) would be set up to require this. This is part of the SSL/TLS protocol, not specific to any language at the application level.
You would use this if the server you are requesting a resource from requires client certificates. The administrator of that server would need to give you the client certificate and private key ahead of time. As mentioned by user349433, this is commonly a PKCS12 (.p12 or .pfx) file.
The server will validate that the client certificate is "trusted" and if it is, it will allow the TLS/SSL handshake to proceed, and CF will be able to write the HTTP request on top of it.
The use case today is to prevent man-in-the-middle attacks, but because of the overhead involved with certificate distribution, revokation, etc. it's not terribly common.
If you want to know more about it, check out TLS 1.1 specification:
https://www.rfc-editor.org/rfc/rfc4346
https://www.rfc-editor.org/rfc/rfc4346#section-7.4.6
You are using client certificate in case if the target server uses that mechanism for authentication. You'll need to obtain specific client certificate from the service provider in order to be able to connect to the service. It's been used for some internet banking applications back in days I believe. Not sure what is the use case today for it, may be distributed corporate networks where you need to connect to corporate server over internet in a highly secure manner?
My scenario:
Many WCF clients which are in environments outside of my control
Server will either be mine OR in an environment outside of my control
So worst case the client and the server is outside of my control. More specifically, I might assume that someone hosting this code could try to maliciously impersonate either the server or the client (the server being more likely). However, the client needs to verify that the server is my code and the server needs to verify that the client is my code. I've seen all the recommendations to use certificates; however, is that an option given my scenario?
One approach I've considered is to write an IClientMessageInspector and an IDispatchMessageInspector to set and verify a custom SOAP header on both sides. I would create an HMAC signature based on a secret key contained within the source code (assume I have a way to keep this hidden) and then verify the digest based on the message body.
I feel like this would work; however, I feel like there might be something more out-of-the-box that I'm missing here. Am I close, way off track? Thanks for any guidance!
Certificates are definitely the way to go in your situation.
Your server will easily be authenticated by clients because it will provide a certificate known to each client, SSL is a good option here.
The server will also be able to authenticate clients by requesting that every client should provide a certificate (server can check for a specific issuer of the certificate - your own issuer in that case).
Now you just need to correctly manage/secure your certificate server to make sure that it won't be compromised.
I don't think there is anything out of the box to do this, simply because it is an unusual requirement for the server to verify that the code on the client calling the service is authorized code.
Generally, it is sufficient to establish trust as follows:
Server has a certificate and service uses SSL - this way clients are confident that they are connecting to the correct server machine.
Clients provide authentication details (eg username/password, certificate etc) to the server so the server knows the connecting client can be trusted.
You are attempting to go the extra step to verify that not only are the users/machines verified, but also that the code running is verified - this is simply overkill. If the code running is not verified, either:
One of the machines has been compromised, in which case you have bigger issues to worry about.
One of your users has written code against your service and is using it 'illegally'. This should not be a problem if your service only allows authorized users to perform 'dangerous' operations.