[Cbor] proposed CBOR format for draft-ietf-mimi-content

Rohan Mahy <rohan.mahy@gmail.com> Wed, 17 April 2024 16:53 UTC

Return-Path: <rohan.mahy@gmail.com>
X-Original-To: cbor@ietfa.amsl.com
Delivered-To: cbor@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 827BFC14F70C for <cbor@ietfa.amsl.com>; Wed, 17 Apr 2024 09:53:38 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -7.094
X-Spam-Level:
X-Spam-Status: No, score=-7.094 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_HI=-5, RCVD_IN_ZEN_BLOCKED_OPENDNS=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001, URIBL_DBL_BLOCKED_OPENDNS=0.001, URIBL_ZEN_BLOCKED_OPENDNS=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com
Received: from mail.ietf.org ([50.223.129.194]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id feLqP9Wywx_2 for <cbor@ietfa.amsl.com>; Wed, 17 Apr 2024 09:53:37 -0700 (PDT)
Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 8E7CDC14F703 for <cbor@ietf.org>; Wed, 17 Apr 2024 09:53:37 -0700 (PDT)
Received: by mail-ed1-x52b.google.com with SMTP id 4fb4d7f45d1cf-570175e8e6fso5931553a12.3 for <cbor@ietf.org>; Wed, 17 Apr 2024 09:53:37 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1713372814; x=1713977614; darn=ietf.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=if0GyECODDXNwX66k2jf5l2KppxD2Bo0mr9y8GE2ycc=; b=Ya6Lej1iOHwpKttCWf8dRT80yQgedkpesgqhCPpmI5jpTjNKmz/moz0gb/CaNyGDFf r/JmcI3pT4GtHwF2dyiF2KND3H/zAXEk1j8T+B523RcKX47WSXCOFtG1fGFOSPePju8O G3TSFb5c9Jzaw2QnIFJY2lHZWw4rajyWUzjbsrfQWS+tmHzlnoFJyLvlM+DUN9xIG0Gx 2qthST2E8mdOBdbhOtYhmt6Dv9jRh0uci0/+Y3/zu/m5AizL7WYoy/g1vY3uGAmvxhh+ gZDWQ3s9yFd5m7q//k0zp6Nnoumar8/Gj8Ep0glfR6U01h8tSv5wbZm3bQtxq062f932 5IfA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1713372814; x=1713977614; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=if0GyECODDXNwX66k2jf5l2KppxD2Bo0mr9y8GE2ycc=; b=Gh8yTVy/IUSspaJXkCRpWrXobxYxQO/ZYZE2pdy8kLb/MyDY73MQ2jSpBsBY9uAyqV poJa/m2B4+zgWxnhWNQ8usqSaXl7jUA1V1pbvYQblrec2hxbkQtNA6+RjwHkwpaU7OlJ BrkD3p/B6a666eyzY7T2XLV8umw1wjT5hw2krhr8S85xTiR2iIzBmRRSdmVK+A7sOa6M qYs03zFWikHjinQs3+yBePWfbu4S/o72kySSw1VH2O82AGWpJzngdvG3HG+/NkPFdmJI +DGgl1BnSbBtLBGz3sByjeaLHBHWMg6ghW9hNNpHz+hFOcB5UBG7k6bmEhukxq4DPjF7 1D8g==
X-Gm-Message-State: AOJu0Yy5XaYVCRugM0BiiHQ2XqdC5aFXMuoI51WZ7U9dLaUobFNcUMvI ZXpHmV9UlynNeQCSTD3aF2b0U1Xp5izWOBPKY59VS9cZjdA4X3thPQs9cGGBq1jEwBAS3atx5MR 5dDg6uGuqJspcqLCyySSpkYurgqx/VW3m
X-Google-Smtp-Source: AGHT+IH4JWEwyK7ESjLVdyZD0AUhBYfunynvSQMEYg/8yQnKzocCqNJCePBLaG00ggmY8w73rEBtzUQcQZh+aPk4NzM=
X-Received: by 2002:a50:9fc3:0:b0:570:1ea8:c50a with SMTP id c61-20020a509fc3000000b005701ea8c50amr163367edf.6.1713372814165; Wed, 17 Apr 2024 09:53:34 -0700 (PDT)
MIME-Version: 1.0
From: Rohan Mahy <rohan.mahy@gmail.com>
Date: Wed, 17 Apr 2024 09:53:22 -0700
Message-ID: <CAKoiRubY_00SKGDkicmDR+b7iy71tMaxcvfRpvt8jCx7SJKSkA@mail.gmail.com>
To: cbor@ietf.org
Content-Type: multipart/alternative; boundary="000000000000f4d0e606164db132"
Archived-At: <https://mailarchive.ietf.org/arch/msg/cbor/SRhWyYmTKuDmxfwPepx2hZ6wkAY>
Subject: [Cbor] proposed CBOR format for draft-ietf-mimi-content
X-BeenThere: cbor@ietf.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: "Concise Binary Object Representation \(CBOR\)" <cbor.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/cbor>, <mailto:cbor-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/cbor/>
List-Post: <mailto:cbor@ietf.org>
List-Help: <mailto:cbor-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/cbor>, <mailto:cbor-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 17 Apr 2024 16:53:38 -0000

Hi,
The MIMI WG is considering using either the TLS Presentation Language or
CBOR as the concrete language in which to define the MIMI content format
<https://www.ietf.org/archive/id/draft-ietf-mimi-content-02.html>. At IETF
119 there was a roughly 50/50 split of the community to use one vs. the
other. To enable a more informed decision I have taken a stab at model
descriptions and example instances in both formats.
(The *semantics* of these messages have been stable in MIMI for the last
year.)

I am asking the CBOR community to please take a look at what I have come up
with to make sure that I am not "holding it wrong", before I update the
document with these messages and submit the next version. While this is my
first project using CBOR, other than feeling that EDN is too complex and
needs to be better specified, I generally have a positive opinion of CBOR
compared to TLS PL.

I have created three CDDL files for the MIMI content format, the MIMI
message delivery format, and the data derived from other layers that could
be available to clients. I have also created 10 instance documents for
various types of content messages, and one instance document each for the
delivery report and implied/derived data. All the instance documents are
available in EDN, regular diagnostic notation, raw CBOR, and pretty printed
hex dumps. All the CDDL files are conformant according to the cddl-rs tool,
and all the .cbor instance documents validate to their respective CDDL
files with the cddl tool.

Note that I took the liberty of using the (unused) arbitrary tag number 62
for "milliseconds since the start of the UNIX epoch" in my examples. Please
consider this a placeholder which can be replaced or omitted.

The CDDL files are inline below and in the root of this repo:
https://github.com/ietf-wg-mimi/draft-ietf-mimi-content/

The instance files can be found in the examples document of the same repo:
https://github.com/ietf-wg-mimi/draft-ietf-mimi-content/tree/main/examples

One representative instance document is included in EDN format below as
well.

Many thanks,
-rohan

## CDDL for message format (mimi-content.cddl)
mimiContent = [
  replaces: null / MessageId,     ; if this message replaces another (ex:
edit/delete/unlike)
  topicId: bstr,
  expires: uint .size 4,
  inReplyTo: null / InReplyTo,
  lastSeen: [* MessageId],
  extensions: {* name => value },
  nestedPart: NestedPart          ; the "body" of the message
]

NestedPart = [
  disposition: baseDispos / $extDispos / unknownDispos,
  language: tstr,
  partIndex: uint .size 2,
  ( NullPart // SinglePart // ExternalPart // MultiPart)
]

NullPart = ( cardinality: nullpart )

SinglePart = (
    cardinality: single,
    contentType: tstr,
    content: bstr
)

ExternalPart = (
    cardinality: external,
    contentType: tstr,
    url: uri,
    expires: uint .size 4,
    size: uint .size 8,
    encAlg: uint .size 2,
    key: bstr,
    nonce: bstr,
    aad: bstr,
    hashAlg: uint .size 1,
    contentHash: bstr,
    description: tstr
)

MultiPart = (
    cardinality: multi,
    partSemantics: chooseOne / singleUnit / processAll,
    parts: [2* NestedPart]
)

InReplyTo = [
  message: MessageId,     ; MessageId of referenced message (hash of
ciphertext)
  hashAlg: uint .size 8,
  hash: bstr              ; hash of unencrypted content or referenced
message
]

baseDispos = &(
    unspecified: 0,
    render: 1,
    reaction: 2,
    profile: 3,
    inline: 4,
    icon: 5,
    attachment: 6,
    session: 7,
    preview: 8
)
unknownDispos = &( unknown: 9..255 ) ; Note: any ext_dispos take precedence

MessageId = bstr .size 32          ; MessageId is derived from SHA256 hash
name = tstr .size (1..255)
value = bstr .size (0..4095)

nullpart = 0                       ; not extensible by design
single   = 1
external = 2
multi    = 3

chooseOne  = 0                     ; not extensible by design
singleUnit = 1
processAll = 2

## annotated instance document for an edited reply message (edit.edn)
[
  / replaces = Reply message                                  /
  h'e701beee59f9376282f39092e1041b2ac2e3aad1776570c1a28de244979c71ed',
  h'',                                 / topicId              /
  0,                                   / expires = never      /
  [                                      / InReplyTo          /
     /  message = Original message                            /
     h'd3c14744d1791d02548232c23d35efa97668174ba385af066011e43bd7e51501',
     1,                                  /  hashAlg = sha256  /
     /  hash                /
     h'6b44053cb68e3f0cdd219da8d7104afc2ae5ffff782154524cef093de39345a5'
  ],
  [                                      / lastSeen (2 items)   /
    /  Reaction message /
    h'4dcab7711a77ea1dd025a6a1a7fe01ab
      3b0d690f82417663cb752dfcc37779a1',
    /  Mention message  /
    h'6b50bfdd71edc83554ae21380080f4a3
      ba77985da34528a515fac3c38e4998b8'
  ],
  {},                                  / extensions             /
  [                                    / body (NestedPart)      /
    1,                                   / disposition = render /
    "",                                  / language             /
    0,                                   / partIndex = 1st part /
    1,                                   / cardinality = single /
    "text/markdown;charset=utf-8",       / contentType          /
    / content = Right on! _Congratulations_ y%27all             /
    h'5269676874206f6e21205f436f6e67726174756c6174696f6e735f207927616c6c21'
  ]
]

## CDDL for implied/derived data fields (implied.cddl)
MessageDerivedValues = [
    messageId: MessageId,          ; sha256 hash of message ciphertext
    hubAcceptedTimestamp: Timestamp,
    mlsGroupId: bstr,
    senderLeafIndex: uint .size 4,
    senderClientUrl: uri,
    senderUserUrl: uri,
    roomUrl: uri
]
MessageId = bstr .size 32          ; 32 octets (the size of a sha256 hash)
Timestamp = #6.62(uint .size 8)    ; milliseconds since start of UNIX epoch

## CDDL for delivery report format (deliver-report.cddl)
MessageStatusReport = [
    timestamp: Timestamp,
    statuses: [ * PerMessageStatus ]
]

PerMessageStatus = [
    messageId: MessageId,
    status: baseStatus / $extStatus / unknownStatus
]

baseStatus = &(
    unread: 0,
    delivered: 1,
    read: 2,
    expired: 3,
    deleted: 4,
    hidden: 5,
    error: 6
)
unknownStatus = &( unknown: 7..255 )

MessageId = bstr .size 32
Timestamp = #6.62(uint .size 8)    ; milliseconds since start of UNIX epoch


Thanks,
-rohan