Re: [Acme] Signing HTTP Messages

Richard Barnes <rlb@ipv.sx> Tue, 23 December 2014 03:43 UTC

Return-Path: <rlb@ipv.sx>
X-Original-To: acme@ietfa.amsl.com
Delivered-To: acme@ietfa.amsl.com
Received: from localhost (ietfa.amsl.com [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id E5BFF1ACD3D for <acme@ietfa.amsl.com>; Mon, 22 Dec 2014 19:43:25 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -0.577
X-Spam-Level:
X-Spam-Status: No, score=-0.577 tagged_above=-999 required=5 tests=[BAYES_05=-0.5, FM_FORGED_GMAIL=0.622, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7] autolearn=ham
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id N7SzGhDUc-Wh for <acme@ietfa.amsl.com>; Mon, 22 Dec 2014 19:43:22 -0800 (PST)
Received: from mail-lb0-f180.google.com (mail-lb0-f180.google.com [209.85.217.180]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 076E31ACCFB for <acme@ietf.org>; Mon, 22 Dec 2014 19:43:21 -0800 (PST)
Received: by mail-lb0-f180.google.com with SMTP id l4so4826079lbv.11 for <acme@ietf.org>; Mon, 22 Dec 2014 19:43:20 -0800 (PST)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=0zbieGnsta4rC1LemhFRT0xqh6sb7H+PGttKCTaOCKs=; b=E6omHFakDRVii3AbOpXlnAhRH+5NwFpEfhDcBkMk1Qvabe6tqroVTPKYGDlcvL7ou0 oBChPitDVY0Z6sO7WTSfW8R1oh2tIjmujOzB0TOgniYcCuhqMsNEhGHII1VthvB6t+Hl XH+0m19iTLVAO89S3r5TkQxgN2CEauaCoZ7M0ojYNRdybmRvo1SID0CWX/ls7qvm6x2c dHNgIj1O2MqOiCRNqE8+2SOxGc/XOunYvcYPcw8tBhZmUF8NXBkaE1vyJ6ey2pTvAgsj P4tEXOnxCwDo0LowV8wm52oCj+ahMPblVU02nvZ17hwnencBbS/oUcUqDQDUl+vb77ID Nzxw==
X-Gm-Message-State: ALoCoQnXXtH2Kqd8pQGvdjO5WWbQp5hm4KZGSRxGD92hMpNlXk3YwJayAFhwGuorFqO2W0c+MiIv
MIME-Version: 1.0
X-Received: by 10.152.206.41 with SMTP id ll9mr14669436lac.62.1419306200337; Mon, 22 Dec 2014 19:43:20 -0800 (PST)
Received: by 10.25.12.215 with HTTP; Mon, 22 Dec 2014 19:43:20 -0800 (PST)
In-Reply-To: <5498A6C9.6030008@digitalbazaar.com>
References: <5494AE04.6070207@digitalbazaar.com> <CAL02cgRH8gNg2TKr+uEnFtmnQm0eR_=pQhFpUVPePqT5c9t6Pg@mail.gmail.com> <5494E2A6.3020508@digitalbazaar.com> <CAL02cgQ=VouAhvZfeW9Sw7U+KJN6pZ-2oA0ck9YD4kfW-oh9Zg@mail.gmail.com> <5498A6C9.6030008@digitalbazaar.com>
Date: Mon, 22 Dec 2014 22:43:20 -0500
Message-ID: <CAL02cgSJfBv-hnUQ-N0V17ACFqWX1EvLXD8wjLZzTDzjWoH0nQ@mail.gmail.com>
From: Richard Barnes <rlb@ipv.sx>
To: Manu Sporny <msporny@digitalbazaar.com>
Content-Type: multipart/alternative; boundary="001a1133af6ae6254d050ad9f9ac"
Archived-At: http://mailarchive.ietf.org/arch/msg/acme/WsoFHq41uzWR97fk2arQ4P4-4tc
Cc: Phillip Hallam-Baker <phill@hallambaker.com>, ACME <acme@ietf.org>
Subject: Re: [Acme] Signing HTTP Messages
X-BeenThere: acme@ietf.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: Automated Certificate Management Environment <acme.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/acme>, <mailto:acme-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/acme/>
List-Post: <mailto:acme@ietf.org>
List-Help: <mailto:acme-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/acme>, <mailto:acme-request@ietf.org?subject=subscribe>
X-List-Received-Date: Tue, 23 Dec 2014 03:43:26 -0000

On Mon, Dec 22, 2014 at 6:18 PM, Manu Sporny <msporny@digitalbazaar.com>
wrote:
>
> On 12/20/2014 12:32 PM, Richard Barnes wrote:
> > Just for context, here's the equivalent using JWS and protecting only
> > the body:
> >
> > ---------------------
> > POST /foo HTTP/1.1
> > Host: example.org <http://example.org/>
> > Date: Tue, 07 Jun 2014 20:51:35 GMT
> > Content-Type: application/json
> > Digest: SHA-256=X48E9qOokqqrvdts8n...yWxBf7kbu9DBPE=
> > Content-Signature: { "header": { "kid": "Test", "alg": "RS256" },
> > "signature": "jgSq...78w" }
> > Content-Length: 18
> >
> > {"hello": "world"}
> > ---------------------
> >
> > Note that using JWS means that I can just toss the header into
> > JSON.parse(), whereas your construction requires custom parsing.
>
> True, although to be fair, it's the same kind of parsing that's required
> for most other HTTP headers (and it was specifically designed this way
> so that the HTTP header parsing mechanism can be re-used).
>
> > And if I have a JOSE library already on hand (of which there are
> > currently a non-trivial number), I can just toss the whole thing in
> > there and call Verify().
>
> Yep, that's nice, if you have already bought into the whole JWS/JOSE
> stack (which I haven't):
>
> http://manu.sporny.org/2013/sm-vs-jose/
>
> > Also, one thing I like about JWS is that you can make it
> > self-verifying.  That is, you can replace the key ID ("kid") with the
> > actual public key ("jwk"), so the verifier can just go ahead and verify
> > without any pre-provisioning of key IDs.  You can also include metadata
> > like certs.  (Yes, that starts to make the header a little big.
> > Deployment consideration :) )
>
> Yes, you could make it self-verifying that way, but that doesn't seem
> likely in practice? Maybe I'm missing something, but the server still
> needs some piece of information (like a key ID that it knows about) that
> it has access to that says that it trusts the signer in the first place,
> right?
>
> The approach we've taken w/ the Linked Data Signature stuff is to make
> kid/jwk a URL, like this:
>
> https://dev.payswarm.com/i/manu/keys/4
>
> That way, you can just fetch the public key as Linked Data and verify
> the message. Same basic process that you're talking about, but the
> approach is what we're currently using to identify keys for both Linked
> Data Signatures and Signing HTTP Messages.
>
> Here's an example of it in action (look at the Authorization HTTP header):
>
>
> http://opencreds.org/specs/source/identity-credentials/#writing-data-to-the-identity
>
> Also note how the same key is used in the "signature" at the end.
>
> > I wouldn't overestimate the complexity of JWS.  Lines of code is a
> > better metric than lines of spec.  It took me a couple of hours to write
> > a JWS library in Go; signing and verification take ~110 lines, most of
> > which is just algorithm mux/demux.
> > https://github.com/bifurcation/gose/blob/master/jws.go#L139
>
> The signing and verification implementation isn't the hard part w/ the
> JOSE stack, it's everything else you have to pull in. My point isn't
> that "it's possible", it's that "a simpler solution exists".
>
> Out of curiosity, where's the test suite for JOSE (and the
> implementations that pass the various specs)? We don't have an official
> one for the HTTP Signatures stuff yet, either, there's only this (and
> it's not that great):
>
> https://github.com/joyent/node-http-signature/tree/master/test
>
> I'm just trying to get a metric on how much I may be "overestimating the
> complexity of JWS". Maybe I am, but from a read of the specs, I think
> it's safe to say that doing HTTP Signatures requires far less code and
> technologies to be pulled in than the JOSE/JWS stack does. Happy to be
> proven wrong, because I can just drop this Signing HTTP Messages /
> Linked Data Signatures stuff if that turns out to be true. :)
>
> > Finally, if you want to protect headers, you can add a protected header
> > to the above to bind in the header string by reference:
> >
> > ---------------------
> > {
> >   "header": { "kid": "Test", "alg": "RS256" },
> >   "protected": base64({
> >     "header": {
> >       "fields": "(request-target) host date digest content-length",
> >       "sha256": "KCBeV_VF5cEzgjY1cNEAkalw94mJwxtXdz874aRUbRM"
> >   })
> >   "signature": "jgSq...78w"
> > }
> > ---------------------
> >
> > ... where the "sha256" field is the SHA-256 digest of the header string.
>
> Yes, you can protect headers like that, but aren't you just going to end
> up needing the equivalent of the Signing HTTP Messages spec at that
> point to specify how everything is serialized and SHA'd?
>
> > Is this making any more sense?  Basically: Use libraries and scale the
> > complexity to the problem.
>
> Sure, it makes sense. As I said before, I think either approach works.
> I'm just trying to figure out which approach is better. So far, the
> arguments seem to be (warning: broad brush generalizations follow):
>
> JWS is better because it's done and there are multiple implementations
> for it. Just re-use what exists, don't invent something new.
>
> and
>
> JWS is worse because it pulls in a lot of complexity that you don't need
> to solve the particular problem you're trying to solve.
>
> I don't think either approach is going to break the Web or the Internet. :)
>

We certainly agree there :)

Without diving into the details above (holiday laziness setting in), I
actually think your broad brush outline is pretty accurate.  The main place
we differ is the complexity of JWS.

When you say "pull in complexity", what do you mean?  At least at the level
of code, all you need is:
-- A crypto library (which you need for Signing HTTP Messages)
-- A base64 encoder (which you need for Signing HTTP Messages)
-- A JSON parser
-- String concatenation (which you need for Signing HTTP Messages)

The signing process in JWS is wonky (some headers protected and some not;
base64.base64), but not rocket science.  And the key discovery has a lot of
options, but is ultimately not complicated -- you either find a key or you
don't.

And it seems like some of these things could be pinned down by using a
profile of JWS -- e.g., requiring all headers be protected and requiring
that at least one of "jwk" or "kid" be present.  That's pretty much what
I've put in for ACME (minus "kid"), and it's basically the same level of
complexity as a raw signature.

Maybe it would be a fun exercise for your winter vacation to try
implementing JWS to see how hard it really is :)

Happy holidays,
--Richard




>
> -- manu
>
> --
> Manu Sporny (skype: msporny, twitter: manusporny, G+: +Manu Sporny)
> Founder/CEO - Digital Bazaar, Inc.
> blog: High-Stakes Credentials and Web Login
> http://manu.sporny.org/2014/identity-credentials/
>