At work, Firefox is our recommended and officially-supported browser. We have historically liked it because (a) it works the same on all platforms, and (b) it implements SSL client authentication correctly. Unfortunately, it seems that very few Firefox developers actually have ever used or tested SSL client authentication, so they regularly find new ways to break it. (This is as opposed to the ways Google and Apple break it, which haven’t changed much. Microsoft actually gets this mostly right, as you might expect for a company that sells an enterprise certificate authority embedded in its operating system, but IE doesn’t implement the standard mechanism for client enrollment, only a Microsoft-proprietary one that isn’t even stable from one release to the next.)
So the current way Firefox screws us is as follows: most users will have the “When a server requests my personal certificate” preference set to “Ask me every time” (which is the default). But that doesn’t really mean “Ask me every time”, it means “Ask me once per browser startup, and then remember whatever I select until I quit.” When that certificate dialog comes up — and oh, by the way, it may pop up over an unrelated browser tab — if you select the wrong thing, too bad, there is no way to recover except by exiting the browser. Firefox will never ask the user to reevaluate the choice it has remembered, not even on shift-reload or clicking the useless “Try again” button on the inevitable error page.
It’s bad enough that Firefox will do this with expired certificates, but what makes it worse is that it will now remember that the user pressed “Cancel” on the certificate-selection dialog. So when that dialog pops up in an unexpected place (for our users, that’s usually the stupid “thumbnail” display that shows by default on new tabs — Firefox re-renders all of the pages shown there) and the user reflexively hits “Cancel”, other internal Web sites on the same server inexplicably fail for no (user-)discernible reason. This is a horrible, horrible UI fail.
What makes it inexcusable is that Firefox knows full well that the server wants a different certificate! The server returns a distinct TLS notification that says, “Hey, your cert’s not valid”, and the sensible thing to do would be to flush the invalid cert from the cache in that case. Even more sensible would be to not send the invalid cert at all: when the server asks for a client certificate, Firefox should make sure that it sends one, that it’s actually valid, and that it is signed by one of the issuers the server indicates it’s willing to accept. If the user for some reason doesn’t want to send a certificate, have them select a distinguished entry in the dialog that reads “Don’t send a certificate to this server”. At the very least, Firefox should at least re-present the certificate selection dialog when the user clicks on the f’ing “Try Again” button on the error page.
(In case you were waiting for me to explain what’s wrong with the other browsers: Opera doesn’t remember the user’s certificate selection at all, ever, which interacts oh-so-well with Apache’s default 5-minute SSL session timeout. Chrome only implements 3/4 of the certificate enrollment protocol: it can do
<keygen> just fine, but chokes when the CA returns the signed client certificate in a PKCS#7 bundle (which our CA sends, and the original Netscape enrollment protocol officially supports, so that the user doesn’t have to separately download the CA certificate). Safari — really, the Mac OS Keychain framework — has consistently had problems selecting the correct certificate to send, although the bugs differ in each Mac OS release; since the server actually says which client CAs it’s willing to accept, there’s no excuse for getting this wrong. Oh, and all of these are things were implemented in Netscape 4, so it’s not like I’m asking for anything cutting-edge here.)