Subject: Client requesting authentication on server & thomson-httpbis-catch

From: "[email-masked]" <[email-masked]>
Date: Tue, 18 Mar 2014 19:11:57 +0100

Hi,

    We have a problem that is somewhat the opposite of the
one described by Martin Thomson recently under draft-thomson-httpbis-catch-00 [1]
though we could make use of it.

We want to deploy client authentication using TLS now [0], with browsers and clients
as they are - that is we cannot wait for TLS1.3, though we look forward to it and
improvements such as draft-thomson-tls-care [3]

Our problem is that we have resources that can return different information
(header or body) depending on the authentication level. Consider for example just
the Allow: header. If a user is not authenticated we return the methods allowed for
an anonymous user.

$ curl -I -k https://bblfish.stample.io/card
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Allow: OPTIONS, GET, HEAD
Content-Type: text/turtle
Accept-Patch: application/sparql-update
Link: <card.acl>; rel=acl, <http://www.w3.org/ns/ldp#Resource>; rel=type

( Following the acls could let a more intelligent user agent know what rights 
  it may have as different users, but not as current browsers are set up [2] )

A server could use the thomson-httpbis-catch WWW-Authenticate header to let 
the client know that authenticated users could do something more if it 
authenticated. Perhaps like this:

$ curl -I -k https://bblfish.stample.io/card
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Allow: OPTIONS, GET, HEAD
WWW-Authenticate: Certificate
Content-Type: text/turtle
Accept-Patch: application/sparql-update
Link: <card.acl>; rel=acl, <http://www.w3.org/ns/ldp#Resource>; rel=type 

But now how does the client authenticate with TLS in the current browsers?
We don't want the client to do a PUT or a POST or a DELETE on the resource
just to do something that it does not have access to. 

There seem to be two choices here:

 1) to have an authentication header that the client could add,
   to ask the server to authenticate it using TLS client certificates. Perhaps
   a client could do 

   GET /card HTTP/1.1
   Auth: Certificate
   ...

  This would be the equivalent in HTTP of what Martin Thomson proposed at the TLS
  level in his "Client Authentication Request Extension for (D)TLS" RFC [3] . 

  2) For the server to publish a link relation to a authentication resource.
   Perhaps with a Link: rel=authn

$ curl -I -k https://bblfish.stample.io/card
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Allow: OPTIONS, GET, HEAD
WWW-Authenticate: Certificate
Content-Type: text/turtle
Accept-Patch: application/sparql-update
Link: <card.acl>; rel=acl, <http://www.w3.org/ns/ldp#Resource>; rel=type 
Link: </login>; rel=authn

   Perhaps for TLS renegotiation a more specific rel=authn-tls would 
be useful. (It's not sure if this answer still needs the WWW-Authenticate: Certificate 
header ). 

   A lot of things are moving in HTTP, so I may have missed the right tool 
for the job.

Henry

[0] Using http://www.w3.org/2005/Incubator/webid/spec/ WebID over TLS
[1] http://datatracker.ietf.org/doc/draft-thomson-httpbis-catch/
[2]  A client could follow the card.acl resource to find out what it is allowed to
do if it is logged in [2], though this would not be too much help for Web Browsers
as these do not necessarily know what their identities are - they can't for
example access the Certificates in their key store - so the JavaScript would have
difficulty finding out what group it belongs to.  Note: The acl link is defined 
in the Web Access Control page of 
     http://www.w3.org/2005/Incubator/webid/spec/
( it needs to be standardised )
[3] http://datatracker.ietf.org/doc/draft-thomson-tls-care/

Social Web Architect
http://bblfish.net/

---

From: "[email-masked]" <[email-masked]>
Date: Wed, 19 Mar 2014 15:42:27 +0100

>  level in his "Client Authentication Request Extension for (D)TLS" RFC [3] . 

So presumably here one could extend the current client "Authorization" header to 
something like 

   Authorization: Certificate

So I see that new schemes can be registered at

   http://tools.ietf.org/html/draft-ietf-httpbis-p7-auth-26#section-5.1.2
   https://www.ietf.org/rfc/rfc2617.txt

This does require server side TLS renegotiation to work, but that's where we are at
present.

>   A lot of things are moving in HTTP, so I may have missed the right tool 

So the question should be: why would one need the "Authorization: Certificate"
if one has the rel=authn, or rel=authn-tls Link ? 

Remembering that servers can also be clients ( we are building linked data crawlers
that need to jump very often across servers all over the internet ), the non-web
browser client could follow policies set by a user as to which sites are ok
to authenticate to, and avoid having to make extra authentication requests.

It also would help servers know when they can do a TLS renegotiation cleanly.
For some reason many browsers ( not Firefox or Chrome ) create an ugly error
page if the authentication fails even when the server is set up in WANT mode
( Ie. in Chrome or Safari if the client does not send a certificate the 
server can still return a valid HTTP response with perhaps a 400 code ). A 
server receiving this certificate would at least know that the client can be
authenticated with a certificate here, and so initiate renegotiation.
( This could even be useful for JS code too, though things get complex with CORS 
there ).

As I understand for HTTP2 this won't do, because TLS renegotation creates issues
in SPDY.

Social Web Architect
http://bblfish.net/

---

From: Mark Nottingham <[email-masked]>
Date: Fri, 21 Mar 2014 12:12:31 +1100

> This does require server side TLS renegotiation to work, but that's where we are at

I think this makes the most sense, in that then you could send

Vary: Authorization

to indicate that the response varies based upon that header. Might be good to put a hash of the cert into the header...

Cheers,

--
Mark Nottingham   http://www.mnot.net/

---

From: "[email-masked]" <[email-masked]>
Date: Wed, 26 Mar 2014 09:34:53 +0100

On 21 Mar 2014, at 02:12, Mark Nottingham <[email-masked]> wrote:

> to indicate that the response varies based upon that header.
> Might be good to put a hash of the cert into the header...

In current popular browsers it is not possible for JS to access the certificates in the keystore, or to
calculate their hashes. [1] This would be possible for web crawlers though ( since those can be programmed to
do whatever we want ). In both cases giving the hash of a certificate in advance could leak identifying 
information, and would require the client to have made up its mind in advance as to what certificate 
it wanted  to use. But I suppose if the request follows a response containing  a 
   "WWW-Authenticate: Certificate"
header or if the client knows that it wants to be identified, then that would make sense anyway.

What was the situation in which you could see an advantage of putting a hash of the cert in the header ? ( which header?)

Thanks,

	Henry

[1] But I have not followed carefully the Web Crypto APIs evolution.

Social Web Architect
http://bblfish.net/

---

From: Mark Nottingham <[email-masked]>
Date: Mon, 31 Mar 2014 14:18:27 +1100

> What was the situation in which you could see an advantage of putting a hash of the cert in the header ? ( which header?)

I was thinking that it was necessary to make caching work. However, I didn’t think it through — if you’re using HTTP auth, shared caches won’t store it anyway.

Cheers,

---

From: Amos Jeffries <[email-masked]>
Date: Mon, 31 Mar 2014 17:40:35 +1300

On 31/03/2014 4:18 p.m., Mark Nottingham wrote:
> 
> On 26 Mar 2014, at 7:34 pm, henry.story wrote:
> 

Except for those must-revalidate cases where caching of auth'd responses
is permitted. Which should not be an issue either.

Amos