Browser is not prompting for a client certificate - authentication

Background:
I am updating an internal application to a two-step authentication process. I want to add a client certificate authentication process (via a smart card) on top of a traditional username/password form. The application is written in C#, hosted on IIS7, and targeting Chrome and IE8.
Problem:
I am having issues with getting the application to prompt the user for a client certificate. I have been debugging the application with the help of Fiddler. When I have a test client certificate saved in Fiddler's user's directory (C:\Documents and Settings\USER\My Documents\Fiddler2), the application works as expected. I am prompted for a PIN number protecting the smart card, and, when entered correctly, takes me to the login form. When I close Fiddler, the application throws a 403 Forbidden error instead (since Fiddler is no longer running and pointing to its certificate). What I haven't been able to figure out is why the application won't prompt for a certificate normally.
Current Server Setup:
Self Signed Certificate was created
443 Binding is pointing at Self Signed Certificate
Anonymous Authentication is Enabled
The Self Signed Certificate was added to both the Trusted Root CA and Intermediate CA (I read that another person had it in both rather than just the Trusted Root CA and that solved their issue, though neither set up has worked for us).
I cleared out the rest of the certificates in the Trusted Root CA that I didn't need (I read elsewhere that having too many certificates would cause SSL to choke).
I am out of ideas to try other than starting from scratch on another server. Does anyone know what the issue might be? This seems like it should be fairly straight forward and that I'm missing something minor. Any ideas are welcomed.
Update:
After spending more time with this issue today, I strongly believe it has to do with IIS7 not being configured correctly (I did not set up it originally). I think this because I enabled Failed Request Tracing, looked at the subsequent .xml files being generated, and saw that a 500 error was being thrown.
Chrome is throwing a "Access to the webpage was denied" message rather than a "403 - Forbidden: Access is denied". I don't know if this helps. I do know that when I do not make certificates required, the site will work as intended. Requiring a certificate is where it fails.
The Application Pool is set to .Net 4.0 | Classic | Network Service.

Your problem is that the browser doesn't either get the request to provide client certificate or there is a security related option to block it from happening. IE offers certificate only if the web site is in correct zone (intranet or trusted sites). Please check this before everything.
If that doesn't help then see this answer for next step. The netsh documentation says:
clientcertnegotiation
Optional. Specifies whether the negotiation of certificate is enabled or disabled. Default is disabled.
Enable that and even the dumbest browser should notice that it is supposed to offer certificate for authentication. To diagnose your problem further you can use WireShark to see the negotiation in action.

In every browser I've seen, the browser will not prompt you to select a certificate if it does not have any certificates signed by a CA the server trusts. So make sure your server is configured with the correct CAs. As Boklucius suggested, you can use openssl to examine the list of trusted CAs your server is sending to clients and see whether the CA you have signed your client certificates with is among them.

Try openssl s_client -connect yourip:443 -prexit
And see if the CA (your self signed cert) is send to the client in the Acceptable client certificate CA names.
you need to install openssl first if you don't have it

I'll throw in a "try restarting the browser" suggestion, particularly if you installed the certificate while the browser was running.

To add a rather painful lesson to the mix: Make sure you quit Skype (or any other application) that eats port 443.
So the idea here is if you are running a dev environment on the same machine (both client and IIS), and your team uses Skype or some other app to communicate.
Watch the hours go by as you try and debug this problem, seemingly doing everything "right", netsh http sslcerts and such, even rebooting but to no avail. Well, turns out Skype will eat 443 so turn it off and "poof" there goes your certificate prompt.
Then feel free to throw things at the wall, shout obscenities or just "Rage, rage against the dying of the light".

Also, make sure Fiddler isn't getting in the way. If you have it decrypting the SSL, it'll corrupt the message back to IE, and it doesn't have the certificate installed, so it can't offer it. Turn off fiddler, and voila, the certificate prompt appears.

In Firefox, if you press 'Cancel' the first time you're prompted for a certificate, and you left the sneaky 'Remember this decision' box checked, then Firefox will remember that and never offer it again.
You can view and delete your previous remembered decisions in Firefox Preferences -> Privacy & Security (about:preferences#privacy), View Certificates, and check the Authentication Decisions tab.

Just connecting to my VPN and trying showed me the certificate prompt. Needs to be done only the first time.

Related

NET::ERR_CERT_REVOKED - only for few clients not all - CentOS Server

Salam,
I installed *.domain.com SSL Certificate in a CentOS 7.1 (apache2) Server, it was Ok first but now some of our client having problem with it,
I tried Server Update.
I tried Cache clear in clients Browsers
I tried different browsers
and I check the date and time.
and I actually do not know it's from the server or its from client side.
Error:
Your connection is not private
Attackers might be trying to steal your information from subdomain.domain.com (for example, passwords, messages, or credit cards). NET::ERR_CERT_REVOKED
Automatically report details of possible security incidents to Google. Privacy policy
ReloadHide advanced
subdomain.domain.com normally uses encryption to protect your information. When Chrome tried to connect to subdomain.domain.com this time, the website sent back unusual and incorrect credentials. Either an attacker is trying to pretend to be support.shamal.net, or a Wi-Fi sign-in screen has interrupted the connection. Your information is still secure because Chrome stopped the connection before any data was exchanged.
You cannot visit support.shamal.net right now because this certificate has been revoked. Network errors and attacks are usually temporary, so this page will probably work later.
Your certificate had been revoked. This can be seen here:
https://www.ssllabs.com/ssltest/analyze.html?d=support.shamal.net
This is a problem with the cert configured on the server. You'd need to ask GoDaddy why this happened - could be you asked to get it reissued, could be they think your untrustworthy for sone reason.
So in theory EVERY client should get a message like that above. But there are some subtleties, which might explain why this is not the case:
If the browser was unable to contact the CA which issued the cert then it will assume he best and assume it's not revoked (so called "soft fail").
Unlike other browsers, Chrome does not do real time checks as whether a cert is revoked by default (as they think it is slow and doesn't add that much protection because of reasons like "soft fail" - a contentious opinion). Instead they rely on a concept call CRLSets which are downloaded periodically by Chrome. This contains a list of revoked certificates. So there is obviously a delay in getting into Chrome and there is some question as to how complete CRLSets are. So this might explain why some Chrome clients are rejecting this and some not. Are the ones that reject it newer version perhaps?
Lastly some tools (particularly Antivirus like Avast or Corporate proxy tools) deliberately replace the cert with one of their own so they can still read the traffic to scan for viruses or for other reasons. Of course they shouldn't do this if a cert is revoked like in this case but stranger things have happened. Double click the green padlock to view the certificate and its chain to see if it was issued by a someone other than GoDaddy.

Why does my wss:// (WebSockets over SSL/TLS) connection immediately disconnect without giving any errors?

Posting this for anybody else running across the same problem.
I was working on a browser client that used stanza.io to connect to an XMPP server (Prosody, in my case). I was using a wss:// connection by default. At some point during development, my client failed to connect at all - it would immediately disconnect silently, without providing any kind of useful error information.
There were no error logs, no error codes, no confirmation dialogs or bars, no indications of what might be wrong.
After hours of debugging, I eventually found the problem; as I was messing around with the configuration of my XMPP server, I had re-generated the SSL certificates for the XMPPd. Since I was using self-signed certificates, this would cause an SSL error. Because I had visited that same URI over HTTPS before, I'd already manually approved the old self-signed certificate - but obviously that approval was no longer valid after regenerating the SSL certificate.
The key to the problem is this: If your SSL certificate causes a warning of any sort, wss:// WebSocket connections will immediately fail, and there is no canonical way to detect this.
As stated above, there appears to be no standardized way to even detect that this problem is occurring, let alone solve it. The best solution to this problem that I have been able to find, is as follows:
If the WebSocket disconnects prior to having received a login confirmation (XMPP-specific), try to make a plaintext ws:// (without SSL) connection to the non-SSL port.
If the plaintext connection succeeds, this means that the server is up - thus the problem is with the SSL certificate. (If the plaintext connection also fails, the server is simply unavailable.)
Display an error to the user, indicating that there was an SSL problem, and that they should check the certificate, with instructions on how to manually approve it.
Provide a target="_blank" link to the wss:// URL, but replacing the protocol with https://. This might be Prosody-specific, but by visiting that URL you will see the SSL warning page. Prosody will display a text that starts with "It works!" after approving the certificate - if the server-side is a custom application, you should display a message saying that "the problem has been solved, you can close this tab now".
In the background, in the main application, keep attempting to reconnect over wss:// every few seconds. Once a connection succeeds, this means the user has approved the certificate. Hide/remove the error and continue the normal connection/login process.
It's far from a smooth process, UX-wise, but it's the smoothest approach I've found. It is not possible to iframe the error page (this was one of my first ideas) - Chrome will refuse to load it at all, Firefox will hide the "Add exception" button, and I'd imagine other browsers exhibit similar behaviour.
Remember that modern browsers do not like self-signed certificates.
Therefore, if your secure WebSocket connection dies before ending the handshake, it could mean that the certificate has not been accepted.
In order to solve the issue, you can:
buy a certificate signed by a Central Authority
simply open in a new
Tab or Window the link of you WebSocket's URI and tell the browser to
trust the connection.
Come back to your WebSocket and it should work.
This is what I did and it worked:
1 - Generate self signed certificate
2 - Create an https websockets server this way

https client certificate logout/relogin

I have a web site using ssl certificate authentication.
How to force the web browser from the server to ask again the certificate to be used?
It would be useable for logout, but the use case here is switching user identity.
I remember something about directing the user to a page which have ssl settings incompatible with the current authentication certificate, but could not find the right settings.
My setup uses apache mod-ssl, but an IIS solution would also be welcome.
Update:
I am specifically asking the server side: how to set up an URL on the same hostname that requires client certificates but rejects all certificates.
For Firefox, javascript:window.crypto.logout(); does work with minor user inconvenience (which I believe could be scripted around).
This is rather difficult in general (and certainly one of the reasons why client-certificate usage can be tedious for most users).
From the client side, there are some JavaScript techniques, but they are not supported across the board (see this question).
Using Apache Tomcat 7, you can invalidate the SSL/TLS session using a request attribute, as described in this question.
I'm not aware of any hook that would let you do this with Apache Httpd (and mod_ssl). The mechanisms usable behind Apache Httpd (e.g. mod_php, CGI, FCGI, ...) generally don't get to be able to alter any settings or environment variables set by mod_ssl, which would be necessary to invalidate the session.
On IIS, this question is still unanswered.
The general way, from the browser point of view, is to go into its setting and clear the SSL state (this varies depending on the browser, but usually requires a couple of dialog boxes at least, not just a quick button, at least not without a plugin).
From a client side web browser you can do this for MSIE (Internet explorer):
your Clear SSL state by going to Tools>Internet Options>Content(tab)>Clear SSL State.
In firefox (prior to version 20) you can do:
Tools | Start Private browsing.
Then visit the page in question. Or then do "Tools | stop private browsing" and then...
Then, when you reload a page you're on it will prompt you to present a new client certificate (if you have more than one from the CA that your server trusts). Othererwise if you just have one certificate it will use the one and only one PKI client cert that is in your store.
For logout read this post: https://security.stackexchange.com/questions/36853/is-it-possible-to-force-a-new-ssl-session#
On the client side, SSL sessions are normally kept in RAM. Internet Explorer, for instance, internally consists of several process that talk to each other, and you have to kill them all to make it forget a SSL session (in practice, this happens only when you have closed all the IE windows).
An alternative can be close browser with javascript.

How to test failing of SSL certificate for certain visitors

For some of my site visitors, the SSL certificate is failing. Whatever tests I do on various browsers for me the SSL certificate is valid.
I can't think of how to test this on client side, and to identify the problem.
How would you do this?
One client gets: fatal certificate unknown
While RouMao's answer is mostly correct, he has missed what is (IME) the most common problem with SSL certificates - the certificate you are using requires an interim certificate from the CA which you have not included in your certificate chain. Most CAs provide an online tool for analysing the certificate - try the one located here.
Also, is there any correlation with which browser being used? Notably, Chrome does not handle SSL v2 by default
Most of the failing of SSL certificates were caused by visitors themselves. Somehow could not tests or verified by server implementation.
Here are some obvious examples:
Your cert is validated since April 1st 2012, but the client's local machine time is set to 2010 -- one year later than current time. In this case, the visitor should encounter problem all the times, until his machine time is later than April 1st 2012.
visitor is behind a restricted firewall. The firewall could terminate the SSL/TLS connection and re-crypt the link with a pseudo/self-sign certificate. Indeed this could be considered as a man-in-middle attach.
The Trusted Root Certification was removed by client himself
it is very hard to fix all these problem. Sometimes, you need to create a client side native application to detect or fix all the possible problems, and require client browser to execute the application each time before it enter the HTTPS mode.
P.S. most of the e-bank application do like this.

SSL certificates with unknown domain name

We're having an issue with securing an intranet / internet website with SSL where
we can't know the qualified domain name in advance.
Basically, I'm trying to make a program that will be installed on a webserver
outside my direct control, to be accessable over intra- or internet. In either case
I want it to be secure via SSL (https). To do this, I would like to include and
install a SSL certificate on the target machine. My installer is fully prepackaged
and should not require any particular during- or postinstall intervention from my
end. Problem is, I can't know ahead of time the target machine's name or domain
name, so as far as I can tell the SSL connection will be returning warnings (or
worse?) when accessed, since the certificate I include will (must) have a different
name on it.
I really want to avoid those warnings, but I still want to keep it secure. Is there
any way to install a SSL connection without certificate warnings without the domain
name known ahead of time?
Thanks for any help you folks can give.
What you want to do is not possible. Here's why.
A certificate will include a set of names (Common Name, possibly along with Subject Alternative Names, possibly including wildcard names).
The client's web browser will do the following:
The user wanted to visit "https://myapp.mydomain.com/blog/posts/1".
The request is via SSL and the domain name in the request is "myapp.mydomain.com".
Get the certificate from the Web server.
Ensure that at least one of the names in the certificate is exactly equal to, or wildcard-matches, the domain name in the request.
Display the page.
Therefore, you need a certificate with the exact domain name (or a wildcard matching the exact domain name) by which the application will be used. And the certificate needs to be available at the same time as, or later than, the time when the exact domain name of the website becomes known, and cannot be made available any earlier.
You seem to be under the misapprehension that somehow a certificate can "create" or "install" an SSL connection. That is false. The Web server - Apache, IIS, Nginx, LigHTTPD, or whichever one you happen to use - is the program that knows how to every aspect of SSL connectivity. The certificate is just a file that the Web server sends to the client, without even opening or using in any way.
Additionally, the author of a webapp to be distributed is not responsible for creating or distributing certificates, and should not be under the misapprehension that he is responsible. Only the website maintainer should be responsible for obtaining a certificate for his website. As another person remarked, in your installation process or perhaps in a post-installation process, you may ask the person installing the webapp for a certificate. But that is the best you can do.
The best you can do is to buy a wildcard SSL certificate - but wait, it's not what you think. You still need to know the second-level domain (the TLD being ".com") ahead of time. You can effectively ask for a cert that covers *.foo.com - then any site, a.foo.com, b.foo.com will be covered. Of course, these certs are more expensive that FQDN certs because you are doing the buggers out of some extra coin.
-Oisin
Each of those sites should have their own SSL certificate. Why not prompt the user to provide the cert file during installation?
In most (if not all) cases, the SSL certificate is associated with the webserver (apache, IIS, etc.) and is not part of your application. It's up to the admin of the web server to install the certificate and not you as the author of the program.
If your installation program does have the ability to modify the web server configuration, and you are willing to have it use a self-signed certificate, you can script the creation of the certificate to allow the domain name to be input. However, I sense this is not really available to you. Also, a self-signed certificate will generally cause certificate warnings.
If I understand you correctly there might be a solution to your problem now. This solution won't help you, however, if you have no control over specifying what SSL certificates are served from the web server where your program is installed (as mentioned by someone else). If your program itself contains a web server you won't have this issue.
If you start with a trusted https website, you can make cross-domain TLS (SSL) XmlHttpRequests to the web servers that are running your application. This is made possible using the opensource Forge project. The project uses a TLS implementation written in JavaScript and a small Flash swf to handle the cross-domain requests. Your program will need to serve an XML Flash policy file that grants the trusted website access to the web server running the application.
Your program will also need to generate a self-signed SSL certificate and upload it to the trusted website. From there, each program's certificate can be included as trusted via the JavaScript TLS implementation. Alternatively, you can have your program upload its certificate to be signed by a CA you create, using a common or subject alternative name that is appropriate for your use (it doesn't have to be the domain name). Then you can use JavaScript to trust the CA certificate and look for the correct name on each certificate.
For more details check out the Forge project at github:
http://github.com/digitalbazaar/forge/blob/master/README
The links to the blog posts at the end provide more in-depth information about how it works.