views:

2215

answers:

1

Wanting to implement authentication by client certificates I am experiencing some issues.

First some facts

The whole site is using SSL. I am using IIS 6 (on Windows Server 2003) and have configured the site to accept client certificates, not requiring them. Most browsers are however implemented in a way so that they will only ask the user for a certificate when it is strictly required. Because of this the authentication model isn't really useful.

Suggestions of my own

My first idea was to set the HttpResponse.Status property but it requires the characters before the first space to be an integer. The useful status for getting a browser to send a client certificate is 403.7 Client certificate required so this will not work (unless you can overwrite it).

I also thought that I would just configure IIS to require client certificates for a specific paths, but this - of cource - works only with physical files and not with routing.

A possible solution is to make a specific folder and require client certificates for it which is more of a hack than a solution. So I would like to avoid this if someone has a better proposal.

Clarifications

I have tested the browser response of both Internet Explorer, Firefox and Chrome (I use Chrome as my primary browser and Firefox as secondary). None of the browsers asks for the client certificate unless I - in IIS - configure it as required.

The HTTP status code 403.7 is due to my understanding allowed as the RFC 2616 only defines the status code as the first three digits. As IIS 6 returns the 403.7 when a client certificate is required, I thought sending it would force IIS into a special mode triggering a requirement.

I guess the problem now is how to configure IIS for requiring a certficate given an virtual path and not a physical.

+1  A: 

There's no difference in the CertificateRequest message sent by a server when the certificate is merely requested, rather than required. The server makes the same request in both cases, and simply terminates the handshake when a client fails to provide a required certificate. Thus, if your browser appears to be ignoring "requests", it should appear to ignore "requirements" too.

Check for the following:

  • Is your browser configured to ignore all certificate requests, never sending one?
  • Is your browser configured to use a given certificate without prompting the user? (In other words, how do you know that the browser isn't sending a certificate?)
  • Is your server actually requesting a certificate?

The way I test this last case is with the OpenSSL (also available in Cygwin) tool:

openssl s_client -connect server.y.com:443 -msg

After the server sends its Certificate message, it will insert a CertificateRequest method which is absent if it is not requesting client authentication. The s_client output looks like this:

<<< TLS 1.0 Handshake [length 0008], CertificateRequest
    0d 00 00 04 01 01 00 00

I'm not sure how it works if the server uses client authentication only on specific paths, because the initial SSL handshake is complete before the client transmits the HTTP request. It would be reasonable for the server to request a new handshake at this point, but I've never tested to see what servers support this.

You can fake an HTTP request via s_client by hand, entering:

GET /your/path/here HTTP/1.1[Enter]
Host: server.y.com:443[Enter]
[Enter]

If you never see a CertificateRequest message at all, your server isn't set up correctly.

Specifying security constraints based on directory structure is quite common and can actually simplify administration of security nicely. Don't feel bad about it if this offers a solution for you.

403.7 is not an HTTP status code. Is that some Microsoft "embrace, extend, and extinguish" subterfuge? In any case, it doesn't sound like the right direction to pursue, since this is a transport layer problem, not an application layer problem.

erickson
Given the way that client authentication is requested, I think your tests were flawed, and that the most likely explanation is that the server was not requesting a certificate at all.
erickson
I am accepting your answer. I am not sure how the IIS are able to require certificates for certain paths, if it has this strong separation between the transport and the application layer. Maybe it redirects and force the handshake on the second request,
troethom
I looked into Tomcat, and it supports path-based cert requests, so I guess it's not uncommon.
erickson