http signature and WebID

Hi all,

I am implementing HTTP Signatures for Authentication.  I was basing
it on on http-signatures-04, as I was only made aware of this version
today:

  https://tools.ietf.org/html/draft-cavage-http-signatures-05

I have not gone through the whole text of 05, as I was
told today on the web-credentials teleconf that there were mostly 
minor differences. Still some of the points may have been addressed there.


Here are some questions and remarks, I gathered while implementing it 
in Scala over the last week. The code is here, compiles but is not yet tested. 

https://github.com/read-write-web/rww-play/blob/dev/app/rww/auth/HttpAuthorization.scala
https://github.com/read-write-web/rww-play/blob/dev/app/rww/ldp/auth/WebKeyVerifier.scala

I jotted the remarks down as they occurred to me during implementation, and
so this can be read as collection of maringal scribbles on the border of
the spec.

• In section 3.1 is written  
[[
 The following sections also assume that the "rsa-key-1" keyId refers to 
 a private key known  to the client and a public key known to the server. 
]]
 it is a bit weird to have a string refer to two different things 
simultaneously. It seems like a way to pave the way for confusion.
( Just a worry )

• What about an upload mechanism to allow a client to upload its certificate 
to the server, so as to not require the communication to depend on
another server being up. Proposed one option for this here:
  https://lists.w3.org/Archives/Public/ietf-http-wg/2015JulSep/0388.html

• keyId: It would be useful if the client could make sure when the KeyId could be a dereferenceable URL. This would allow a client to not have to upload the certificate
when making a connection. Something like that is described in:
  https://lists.w3.org/Archives/Public/ietf-http-wg/2015JulSep/0388.html

It may just be best if the spec was clear that the keyId must be a URI, but could
be a relative one, which may be access controlled, and so only known to the server
itself. Otherwise one is not quite sure how to interpret this.

• Headers maintenance over transport:

  'If there are multiple instances of the same header field, all
   header field values associated with the header field MUST be
   concatenated, separated by a ASCII comma and an ASCII space `, `,
   and used in the order in which they will appear in the
   transmitted HTTP message.'

 - what is the chance that proxies actually somehow reorder or add headers to a
  message sent? Is there an RFC that actually states this should not be done? 
  ( so that one can refer to that when one finds a problem? )
 - same questions re JS libs: do they keep the order of headers or other such things.
 - what are the headers that XMLHTTPRequests clients can actually control?
   ( Is there perhaps a howto somewhere for these types of issues ? )
 - for POSTing, or PUTing of larger contents I suppose the JS may not at all be in control of
  the number of chunks by which the content is sent, so the Content-Length field may only 
  be calculatable very late in the game.
 
• reference to HTTP/2 incorrect

    If the header field name is `(request-target)` then generate the
    header field value by concatenating the lowercased :method, an
    ASCII space, and the :path pseudo-headers (as specified in
    HTTP/2, Section 8.1.2.1 [5]).  
  ...
    [5] http://tools.ietf.org/html/rfc3447#section-8.2.1
    
    but RFC3447  "Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography"
    does not have anything about :method
 
   I think the reference was meant to be to
    https://httpwg.github.io/specs/rfc7540.html
   "8.1.2.3 Request Pseudo-Header Fields"


• Is there a test suite? 
 I need to build one, but would be happy if I could verify against another one.

• Similar specifications:
  
 - Amazon has a signature based auth mechanism
  http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html
 - Akamai also: 
  https://developer.akamai.com/introduction/Client_Auth.html
 - OCLC developer network:
  https://www.oclc.org/developer/develop/authentication/hmac-signature.en.html
 - SoLiD ( Social Linked Data ) 
  https://github.com/solid/solid-spec#webid-rsa
  ( though there is a discussion there on moving to something more widely adopted )
 - A proposal by Jeff Lindsay
   http://progrium.com/blog/2012/12/17/http-signatures-with-content-hmac/
 - Microsoft Azure: 
   https://msdn.microsoft.com/en-us/library/azure/dd179428.aspx

 It would be worth having a web page that lists howtos and other uses that go beyond the
RFC. It could also list such other protocols. Those don't seem to be correctly specified, but
knowning that Amazon has something similar makes a pretty good case for it.

WebID Integration ( http://webid.info/spec/ )
-----------------

I have not yet implemented this. But these are some initial thoughts.

Verifying the public key is the first step. A public key can actually be used as a global identifier. But Web Access Control using just public keys would be quite cumbersome:
 - a user may have one public key per device and even per application
 - public keys should be changed if there is reason to believe the private key may have
   been compromised, or if the hardware has been lost
 - filling ACL files with public keys would render them quite heavy ( though here clearly
  using a URL to refer to the key can solve this problem )

Now it is also possible that a key be linked to one or more WebIDs (which logically would therefore refer to the same agent). These WebIDs could potentially be on different domains.

If they key points to the WebID by containing triples - expressed in a hypothetical <android> document in n3 like this

<android#key> cert:modulus "..."^^xsd:hexBinary;
       cert:exponent 65537;
       is cert:key of <profile#me> .

- and the server verified the key using the Signature header, then if the WebAccessControl rule for the given resource were expressed in terms of one of those WebIDs, the server would still be required to dereference the WebID and check if it also had a pointer to the key. So for
example the <profile> resource would say something like this:

<profile#me> cert:key <android#key>, <desktop#k> .

This type of verification has to be done or else any key could claim to be tied to any WebID.

On the other hand it is does not seem necessary to have the key point to the WebID, as
described in the <android> document above. It is the WebID Profile document that is the authority of what its keys are, not the other way around. This would allow the WebKey
to be used both when no tie in to a WebID is needed such as a very simple resource ( for
the sake of the example let's name it <desktop> ) that would just contain the following:

<desktop#k> cert:modulus "..."^^xsd:hexBinary;
            cert:exponent 65537 .

his would allow some resources to be made available only to actors that can use one very precise key with an Web Access Control (WAC)  of the form ( http://www.w3.org/wiki/WebAccessControl )

[] acl:accessTo <card>; 
   acl:mode acl:Read, acl:Write;  
   acl:agent [ cert:key <android#key> ] .

Anyone coming across this WAC would have very little 
information about the owner of that key, and his social network.

In that case though clients that had a WebID and wanted access to a resource
that gave access to the referent of their WebID, would need to pass that 
information along in the request header. 


* should the WebID be passed in the signature?

  It may make more sense to have a WebID header, and for to be added to the headers field in the headers attribute of the Signature request. 
Currently the WebID/SoLiD group is using the User header to pass the webid 
https://github.com/solid/solid-spec#finding-out-the-identity-currently-used

  But the problem here may be if a client sends two signatures, then it would not be clear
which WebID to associate with which signature. Is that actually likely? ( I don't know yet )
If so then one would need to actually add a webid="http://bblfish.net/#me" attribute value
in the Signature header.
 
* How does the server hint that a WebID may be of interest to it?
 The signatures spec seems to say that this can be done by passing the field in the
"headers" parameter of the WWW-Authenticate header.

  "The server may optionally specify which
   HTTP headers it expects to be signed by specifying the `headers`
   parameter in the WWW-Authenticate header."

  So this means I suppose that the server can add some headers such as User used by the 
SoLiD group. But then we still have the issue mentioned previously of what happens if
the client sends more than one signature...

* I suppose a future WG could have as one of its roles to merge the cert ontology that
WebID uses with the one that digitalbazaar has been developing. 


I thought I'd stop here, as this is already rather long. On the whole the spec looks
pretty good. I'll have to test it further in browsers to get a full understanding of it.


All the best,

Henry

http://bblfish.net/

Received on Tuesday, 13 October 2015 20:11:18 UTC