- 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