- From: Bruno Harbulot <Bruno.Harbulot@manchester.ac.uk>
- Date: Wed, 20 Jan 2010 15:33:25 +0000
- To: mrex@sap.com
- CC: tls@ietf.org, ietf-http-wg@w3.org
Hello, Martin Rex wrote: > Bruno Harbulot wrote: >> - If a certificate is mandatory, the 'require' mode leads to a handshake >> error code on the client side, resulting in an abrupt error message, >> which is confusing for most users. > > Clarifying: If the server's TLS is configure to require a client-cert, > the server's TLS will produce the error message (and terminate the > TLS handshake with a fatal alert message), which in turn will > cause the client TLS implementation to report an error. Indeed. >> To try to solve this, I would like to suggest the introduction of >> something along the lines of a 'transport' challenge, implying that the >> authentication mechanism is outside the scope of HTTP itself. >> This could be something like: >> - WWW-Authenticate: transport >> - WWW-Authenticate: transport mode="tls-client-certificate" >> >> To this, could be added parameters describing what kind of certificate >> is preferred. Just to clarify, I'm not suggesting implementing the client-certificate negotiation (or renegotiation) at the HTTP level. I'd just like to address a gap in the HTTP authentication space, more specifically, the 401 status code says there MUST be one or more 'WWW-Authenticate' header (with one or more challenges each). If an HTTP client tries to access resource on an HTTP server that is protected and where authentication is required, the HTTP server will respond to the request with an HTTP 401 status code, and, for example "WWW-Authenticate: Basic xxxxx", thereby telling the client that it should send the request again, with appropriate authentication information. This mechanism is useful in that: - the WWW-Authenticate in the HTTP header is sufficient for the browser to know what to do (e.g. pop-up). - a entity can still be associated with a response with 401 status code: there can be a page telling the user why access wasn't granted, where to get an account, etc. At the moment, if a browser tries to connect to a page that requires TLS client-certificate authentication for granting access, and if this certificate isn't provided (irrespectively of how the TLS handshake went), the server will be most likely to return a 403 status, which implies that "the request SHOULD NOT be repeated" [RFC2616]. The current behaviour could be summarised as follows: - Server configured for 'require' - Client sends a suitable certificate. - If this user is authorised: HTTP 200 OK, otherwise HTTP 403. - Server configured for 'require' - Client doesn't send a certificate. - Server's TLS error message -> Client error message. This is the problematic behaviour in browsers: it confuses users and doesn't give much of a chance to tell them what was wrong with their certificate or where to get their certificate. - Server configured for 'request' - Client sends a suitable certificate. - If this user is authorised: HTTP 200 OK, otherwise HTTP 403. - Server configured for 'request' - Client doesn't send a certificate. - Will probably get 403, without a way to tell to send a certificate this time. In HTTP terms, the 'require' configuration is just "rude" and the current 'request' configuration (without proper 401/WWW-Authenticate response) doesn't give much opportunity to provide an explanation and to try again. This also prevents the server to present the client-cert authentication as one of a number of challenges. For example, using 'WWW-Authenticate', a server can offer an HTTP Basic challenge and a SPNEGO challenge at the same time, leaving the choice to the client. > Unfortunately, the issue is _much_ more complex. > Difficulties you have to address: > > 1. whether or not the server requests a client certificate > is a decision of the server alone. The client must not > send an unsolicited client certificate (that should cause > compliant servers to abort the handshake). Indeed, but I don't think there would need to be a "pre-emptive" 'Authorization' header in the same way in can be done with HTTP Basic for example. In fact, I don't think a request, even as a response to a 401 status would need to have such an 'Authorization' header. All it would need, would be to have sent the client-certificate, through the TLS channel (perhaps re-negotiated, perhaps after a new connection). This could be a good way to indicate to a browser that, even on the first attempt, it hadn't presented a certificate by default (assuming the server is in 'request' mode) for the first attempt, it should tell its TLS layer to send one for the second attempt. Perhaps some indication of "realm" or something similar might help the browser make a better choice as to which certificate to use (this could be combined with improvement in user interfaces). > 2. there currently is _no_ standardized fashion for TLS to > negotiate certain aspects of client certificate authentication > > a) client->server signaling that client des not have > a certificate (or is determined to not send one) > > b) client->server signaling that client has a certificate > and is willing to use it for client certificate authentication > (provided that server certificate validation succeeds). I suppose you mean signaling before the handshake? Otherwise, sending an empty or non-empty Certificate message (from client to server) during the handshake should cover those two cases, respectively. Isn't this standard? I'm not sure what the problem would be otherwise. > c) server->client signaling that client may send *any* > certificate with the promise that the server will _NOT_ > abort the handshake when the server does _not_ have a > trust anchor necessary to verify the certificate sent > by the client (requiring the server to either withhold > such a client cert from the server application, as if > the client had _not_ sent any cert -- at least _not_ > provide such a client cert to server apps in the same > fashion as authenticated client certs. > > SSL/TLS client cert authentication kind-of blindly assumes > a PKI and SSLv3&TLSv1.0 _require_ a server to send a > non-empty list of trusted CAs. Semantics of empty ca_list > in TLSv1.1&1.2 is underspecified. In my experience with SSLv3 and TLSv1.0, more particularly Java's JSSE and Apache Httpd, even though there was no mention of emtpy ca_list in these versions, it works fine. In Apache Httpd, using SSLCADNRequestFile with a file containing just a line return is enough to make it send an empty ca_list. Combined with "SSLVerifyClient optional_no_ca", it can accept any self-signed (or not) certificate. In Java, setting the TrustManager do to this works fine: public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } (That's something we use doing the FOAF+SSL work, where we verify the certificate at the application level, once the handshake is finished.) This being said, I'm not suggesting making changes to the TLS specification, just conveying some extra information at the HTTP layer regarding the authentication that happens at the TLS layer, for better integration with the HTTP mechanisms. > 3. (Bodo Moeller recently explained this to me): > cryptographic algorithm constraints on client certificates > According to rfc-5246 Section 7.4.6. there are constraints > if the client certificate is of one of these types: > rsa_fixed_dh, dss_fixed_dh, rsa_fixed_ecdh, ecdsa_fixed_ecdh > > http://tools.ietf.org/html/rfc5246#page-56 > > restricting compatible client certs that can be used for > client cert authentication in TLS to _both_, characteristics > of the cipher suite plus characteristics of the server certificate > > This additional restriction does not apply to client certificates > rsa_sign, dsa_sign (and marginally to ecdsa_sign). That's something I would leave as it is, for the TLS handshake to do. I don't think an WWW-Authenticate header should influence this. If a 'WWW-Authenticate' for TLS certificate authentication was also to specify which certificate was preferred (something I'm not sure about at the moment), then the client would probably have to abide by the TLS requirements first and use the HTTP preference as a further hint only. For example, the ca_list sent by the server could contain a number of DNs, but the 'WWW-Authenticate' would have an order of preference, for this particular resource; if the preference list at the HTTP level was incompatible with the ca_list at the TLS layer (or other TLS requirements as you mention), then the TLS layer would prevail. >> As a side note, I also think that such a mechanism could partly help >> with the TLS renegotiation issue (still discussed on the IETF TLS >> mailing list). Indeed, if the HTTP framework was able to detect a >> renegotiation had occurred, it could make the client re-send the request >> post-negotiation (rather than assume that the certificate presented >> during the second handshake were also valid for the request sent before). > > Changing/switching client identities is also a somewhat underspecified area. > > In theory, clients can offer some means to "flush" the client-side > TLS session cache (several browsers have that, I think), but it > may be a function hidden in some configuration options many casual > users have never used or maybe even looked at. Indeed, in Firefox you can do this by logging out of the software security device (Preferences -> Advanced -> Encryption -> Security Devices -> 'Software Security Device' -> Log Out), and, in Internet Explorer: Internet Options -> Content -> Clear SSL State. > I'm not sure that current / commonly used browsers, which offer > multi-windows and tabbed browsing, have an adequate client-side > session cache management (in the browser) to reliably manage many > parallel sessions with the exact same server and individual > TLS client identities/credentials for each session. That's unfortunately not specific to TLS authentication. Browsers tend to have a single sign-on across tabs and windows, where you're logged on forever across all of them, for Basic/Digest/TLS/Cookie authentication with the exception that only cookies/forms tend to have a convenient log out mechanism. (Again, logging out of the software security device also logs you out in Firefox, but that's quite far away.) Best wishes, Bruno.
Received on Wednesday, 20 January 2010 15:33:55 UTC