[Acme] Signed JSON document / Json Content Metaheader / JSON Container

Phillip Hallam-Baker <phill@hallambaker.com> Wed, 28 January 2015 18:15 UTC

Return-Path: <hallam@gmail.com>
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 986911A8882; Wed, 28 Jan 2015 10:15:01 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: 1.323
X-Spam-Level: *
X-Spam-Status: No, score=1.323 tagged_above=-999 required=5 tests=[BAYES_05=-0.5, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, FM_FORGED_GMAIL=0.622, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, J_CHICKENPOX_45=0.6, J_CHICKENPOX_66=0.6, SPF_PASS=-0.001] autolearn=no
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 UqEYRHfX2HHU; Wed, 28 Jan 2015 10:14:59 -0800 (PST)
Received: from mail-qg0-x22e.google.com (mail-qg0-x22e.google.com [IPv6:2607:f8b0:400d:c04::22e]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 48AD31A8880; Wed, 28 Jan 2015 10:14:59 -0800 (PST)
Received: by mail-qg0-f46.google.com with SMTP id i50so17816854qgf.5; Wed, 28 Jan 2015 10:14:58 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:date:message-id:subject:from:to:content-type; bh=9HLbTIrI7iS62akaHdulhZR8CkLcSN4Xs738HmgYUyw=; b=Zk+Ht1E5ODPiDD90+rb3wrnUDzDBudzzbI9dpkQrXzC4zEV6rnH1Y3NS7IUp3ZFqlO /bY7kqZeBWaof/3x7F41wYrji7VopF7aVrwyiwBIgfBXQX3MUXK/mvs//wix/1VI//ih LkDWfifO/MTD8ERgdubmCTUkyNevIQT68mEpn40QKQuz64sgRGk9z27+Pp7oCLNx8fIJ cI2LjHC4CHvDl/3nWdoNNUc0YswMJKpvA7xt+3Nt48mOWehFysE0po3djbWVgWOd+iV4 mXb/gc53WTf6kBJEm/PllqoYfNVY1hXNBGStMbyXIRA0zQJpdZ2FGwB3o+elg+hPqh8G wgCA==
MIME-Version: 1.0
X-Received: by 10.224.23.6 with SMTP id p6mr16034851qab.55.1422468898210; Wed, 28 Jan 2015 10:14:58 -0800 (PST)
Sender: hallam@gmail.com
Received: by 10.140.92.135 with HTTP; Wed, 28 Jan 2015 10:14:58 -0800 (PST)
Date: Wed, 28 Jan 2015 13:14:58 -0500
X-Google-Sender-Auth: WANXu9W7l2p3nQ-iU42BPHhz_4g
Message-ID: <CAMm+Lwh12jzrH3ZVaS4HTqkNZkteg9mL+n6LYRsj5P1r-Q-DbQ@mail.gmail.com>
From: Phillip Hallam-Baker <phill@hallambaker.com>
To: JSON WG <json@ietf.org>, "acme@ietf.org" <acme@ietf.org>
Content-Type: multipart/alternative; boundary="001a11c2b31c61cacc050dba596f"
Archived-At: <http://mailarchive.ietf.org/arch/msg/acme/I6dVyn4s--bUHD8JIBG142lZLl0>
Subject: [Acme] Signed JSON document / Json Content Metaheader / JSON Container
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: Wed, 28 Jan 2015 18:15:01 -0000

All,

I would like to propose a spec similar to the JSON log file spec but with
the purpose of being a container for JSON signatures. The immediate
application for this might be for ACME or other JSON/Rest Web services.

The elevator pitch for the idea is that a JSON Container would be a JSON
Metadata blob with the content being described appended to the end in a way
that makes the separation between content and metadata simple and
unambiguous.

<JSON-BLOB> [Separator] <content-blob>

Advantages:

* Can read the metadata for a file etc with a plain ASCII editor or command
line tools like cat, more, etc.

* Avoids the need to BASE64 armor the content. So if the content is JSON or
other ASCII/Unicode text it remains readable in an ASCII/Unicode editor.

* Can add signatures, digests and other metadata items to content in a
simple regular fashion.

* Content and metadata can be transported as a simple regular blob that is
fully abstracted from and independent of the transport and without the need
for canonicalization, XPath or other complications.


Right now, the IETF spec for describing content metadata is based on
RFC822. And by 'based on', I mean that it is a find the needle in the RFC
haystack approach. RFC822 style content headers as currently used have
several disadvantages:

* It is a flat structure, headers can have attributes but trying to add
more structure is painful.

* It is a historical artifact and content metadata headers are mixed in
with protocol metadata headers without rhyme or reason.

* It is not JSON and JSON is the spec we are now converging on for this
type of work. It has all the expressive capabilities of XML and ASM.1
without the insanities and stupid. It is as easy to read and write as
RFC822 but without the limitations.


The spec itself would be simple, its
basically draft-ietf-json-text-sequence applied to a sequence of one json
object and one content blob.

JSON sequence specifies that "A JSON text sequence consists of any number
of JSON texts, all encoded in UTF-8, each prefixed by an ASCII Record
Separator (0x1E), and each ending with an ASCII Line Feed character (0x1A)"

This is not ideal for JSON Container. We would prefer that the character
which is illegal in a JSON document be the one that is the separator
between the header and content.

All indexes used in the metadata header are calculated from the Record
Separator byte, the first byte following being byte 0 and so on.


Applying this in a Web Service is very simple, our messages now have the
form:

POST / HTTP/1.1
Host: example.com
Content-Type: application/json-container
Content-Length: 666

{ "Signature" : "wefwkjefkljwehfjklwhejkflh" }

<0x1E>{ "Service-Type" : "acme.ws",
   "Transaction-ID" : "2h23roih23oih23orh",
   "Register" : { ....<web service parameters here> ... } }

Where <0x1E> is the record separator character.

The scope of the signature is the content, the whole content, AND NOTHING
BUT THE CONTENT. Signing headers is a mugs game. Put all the information
that matters into one blob and sign the blob. Do not present developers
with an IKEA self-assembly job.

So to prevent protocol substitution attacks, the service identifier and the
method name wrap the method parameters. In a response, the service
identifier, response code and transaction ID wrap the response data for the
same reason.


Applying the scheme to stored data in a file system is a little different.
First we have to develop a file extension convention:

file.jpg  becomes file.jpg.jsonc

Many jsonc aware applications will have to share data with applications
that are not aware. So we need the option of storing metadata in a separate
file when that is convenient:

The metadata for file.jpg is stored in file.jsonm

In some circumstances we might want to keep the metadata for all the files
in a directory or tree in one file, a metadata container. This could be
jsonmc.jsonmc appearing in either the directory a file is in or one of the
directories above it.

A metadata container would be a JSON container and begin with the usual
metadata header for that file followed by a JSON sequence of entries per
file. If this contains a signature, the file entries can just be digests.


Notice how we have just developed a format that allows us to sign a
complete code distribution including content data very easily. This is
obviously out of scope for ACME but the fact that an approach transfers so
neatly to a completely different problem suggests that it is the right
track.