Re: [Acme] Signing HTTP Messages
Richard Barnes <rlb@ipv.sx> Sat, 20 December 2014 17:32 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 5CF211AC3DF for <acme@ietfa.amsl.com>; Sat, 20 Dec 2014 09:32:14 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.977
X-Spam-Level:
X-Spam-Status: No, score=-1.977 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, 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 cfpQBUmZzdtt for <acme@ietfa.amsl.com>; Sat, 20 Dec 2014 09:32:10 -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 130F21A8A55 for <acme@ietf.org>; Sat, 20 Dec 2014 09:32:10 -0800 (PST)
Received: by mail-lb0-f180.google.com with SMTP id l4so2206204lbv.25 for <acme@ietf.org>; Sat, 20 Dec 2014 09:32:08 -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=0z1AZu8N96nK8FaTH3QpTLAsuVfBFSMPhWpjBZCNmcE=; b=bfRAfunrssZ5v+56ZIMlHW5vt44N5QfSDvWC4D3y/rQvmYaBfmRQbN+vv9UMM3WYPw b+/acGEA3rqoc7HdhV7Slc33CC0BXLhNu1CKassUvUlT0nEjs7KCbq8EVNUFy+G+DEUn Yfr4IMSu9zu39xXYpES00bxh1WjzabdEmOmE1RlKd05QUdKz+vWd61FzyrVZCQa9/TrJ eV8/VjvAiCfC8FkehUZk6MEIZBYWS34dm7Jmsi5ZR7I38lPdCT7NN+xeaKhxgZosXk6b WbXeklfQ3GJ0Nvcu7wdImbOfxRaaYQ4B471FBbkJW26Bqn+ok034y+fyFOSqMGpCqe0S WGEg==
X-Gm-Message-State: ALoCoQkBpJXtGQY8Nl/RuDWwnHdZAqQoEm73xq9TVztiT5feS06Cbr4tfOnYu1COqfKKpvlc1NX/
MIME-Version: 1.0
X-Received: by 10.152.26.201 with SMTP id n9mr13784327lag.50.1419096728506; Sat, 20 Dec 2014 09:32:08 -0800 (PST)
Received: by 10.25.12.215 with HTTP; Sat, 20 Dec 2014 09:32:08 -0800 (PST)
In-Reply-To: <5494E2A6.3020508@digitalbazaar.com>
References: <5494AE04.6070207@digitalbazaar.com> <CAL02cgRH8gNg2TKr+uEnFtmnQm0eR_=pQhFpUVPePqT5c9t6Pg@mail.gmail.com> <5494E2A6.3020508@digitalbazaar.com>
Date: Sat, 20 Dec 2014 12:32:08 -0500
Message-ID: <CAL02cgQ=VouAhvZfeW9Sw7U+KJN6pZ-2oA0ck9YD4kfW-oh9Zg@mail.gmail.com>
From: Richard Barnes <rlb@ipv.sx>
To: Manu Sporny <msporny@digitalbazaar.com>
Content-Type: multipart/alternative; boundary="089e0160a70667a970050aa9343b"
Archived-At: http://mailarchive.ietf.org/arch/msg/acme/4yxjvBxdp1EwQ8eOpO_T_-kVG7E
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: Sat, 20 Dec 2014 17:32:14 -0000
On Fri, Dec 19, 2014 at 9:44 PM, Manu Sporny <msporny@digitalbazaar.com> wrote: > > On 12/19/2014 07:35 PM, Richard Barnes wrote: > > Thanks for reaching out. Just so the context is clear, there's > > nothing in ACME currently that uses an HTTP header to convey a > > signature structure. It's all in the body. > > Good to know. My assumption was that ACME is being built on top of JOSE. > > > The draft-cavage- document had been pointed out to me before. It's > > too ambitious :) > > Haha, we were trying to do something sensible, not ambitious. :) > > > That draft tries to solve the problem of signing an HTTP message. > > That's a fiendishly difficult problem because it involves headers, > > whose complicated, ambiguous syntax is inimical to signing. Also, > > middleboxes routinely tamper with headers. > > Yes, both rabbit-holes were taken into account when designing the spec. > Just to be clear, we're not trying to sign /all/ HTTP headers in a > message, the sender gets to pick which headers to sign, the server gets > to decide whether or not that's good enough for the type of request. > > The developer can choose specific headers that don't have ambiguous > syntax and ones that middleboxes are most likely not to modify. > > I think we address these two concerns in the "Signing HTTP Messages" > spec as best we can. > > > All I want is to sign the body of the message. HTTP treats the body > > as an octet string, which means there's no c14n issues. And > > middleboxes tamper with bodies much less often. > > I think you can do this easily with the Signing HTTP Messages spec. Just > digitally sign the Digest header (along with a few others to prevent > replay attacks if doing so is important to the use case). > > There's an example of doing this in this section: > > https://tools.ietf.org/html/draft-cavage-http-signatures-03#section-3.1.2 > > > Also, the draft-cavage- document invents its own signature syntax, > > when it should just use JWS. > > What do you mean by "signature syntax"? Do you mean "the way the bytes > are constructed in order to sign them"? > > The normative bits of the Signing HTTP Messages spec are roughly 5 pages > in length vs. the 50+ pages in JWS. It didn't seem necessary to pull in > all that unnecessary bloat just for signature string construction. > > It's true that maybe the length of the JWS spec is due to necessary > security precautions that the Signing HTTP Messages spec overlooks, but > if it does overlook something, we're not aware of it. > > Happy to be convinced otherwise, but I'd rather not expose implementers > to JWS or JOSE in general. > > > So my proposal was: Start with a Content-Signature header that just > > has a JWS covering the body. > > Sounds like a good idea. I think you could simplify it further and make > it easier to implement. > > > In some cases that's all you want, and it's a more tractable problem > > than covering HTTP messages as a whole. > > I think you may not quite understand what we're trying to do w/ that > spec. Or, I don't understand the nuance that you're getting at. Either > way, we're miscommunicating. :) > > > Then, if you want to protect HTTP headers later, you can add a > > signed attribute to the JWS (e.g., > > digest(canonicalized-header-info)). > > > > Does that make sense? Is that at all relevant to your use cases? > > What you're trying to do certainly makes sense, and if you want to use > JWS to solve the problem, I guess you could do that. I still hold that > the Signing HTTP Messages spec sounds like it could solve your problem > in a much simpler way. For example, here's what a full solution might > look like: > > --------------------- > POST /foo HTTP/1.1 > Host: example.org > Date: Tue, 07 Jun 2014 20:51:35 GMT > Content-Type: application/json > Digest: SHA-256=X48E9qOokqqrvdts8n...yWxBf7kbu9DBPE= > Signature: keyId="Test",algorithm="rsa-sha256", > headers="(request-target) host date digest content-length", > signature="jgSqYK0yKclIHfF9zdA...NqNyAXKdxZZItOuhIs78w=" > Content-Length: 18 > > {"hello": "world"} > --------------------- > Just for context, here's the equivalent using JWS and protecting only the body: --------------------- POST /foo HTTP/1.1 Host: 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. 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(). 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 :) ) 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 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. Is this making any more sense? Basically: Use libraries and scale the complexity to the problem. --Richard > Thoughts? > > -- manu > > -- > Manu Sporny (skype: msporny, twitter: manusporny, G+: +Manu Sporny) > Founder/CEO - Digital Bazaar, Inc. > blog: The Marathonic Dawn of Web Payments > http://manu.sporny.org/2014/dawn-of-web-payments/ >
- Re: [Acme] Signing HTTP Messages Richard Barnes
- Re: [Acme] Signing HTTP Messages Richard Barnes
- Re: [Acme] Signing HTTP Messages Richard Barnes