diff options
Diffstat (limited to 'doc/rfc/rfc8610.txt')
-rw-r--r-- | doc/rfc/rfc8610.txt | 3587 |
1 files changed, 3587 insertions, 0 deletions
diff --git a/doc/rfc/rfc8610.txt b/doc/rfc/rfc8610.txt new file mode 100644 index 0000000..bec963a --- /dev/null +++ b/doc/rfc/rfc8610.txt @@ -0,0 +1,3587 @@ + + + + + + +Internet Engineering Task Force (IETF) H. Birkholz +Request for Comments: 8610 Fraunhofer SIT +Category: Standards Track C. Vigano +ISSN: 2070-1721 Universitaet Bremen + C. Bormann + Universitaet Bremen TZI + June 2019 + + + Concise Data Definition Language (CDDL): A Notational Convention + to Express Concise Binary Object Representation (CBOR) + and JSON Data Structures + +Abstract + + This document proposes a notational convention to express Concise + Binary Object Representation (CBOR) data structures (RFC 7049). Its + main goal is to provide an easy and unambiguous way to express + structures for protocol messages and data formats that use CBOR or + JSON. + +Status of This Memo + + This is an Internet Standards Track document. + + This document is a product of the Internet Engineering Task Force + (IETF). It represents the consensus of the IETF community. It has + received public review and has been approved for publication by the + Internet Engineering Steering Group (IESG). Further information on + Internet Standards is available in Section 2 of RFC 7841. + + Information about the current status of this document, any errata, + and how to provide feedback on it may be obtained at + https://www.rfc-editor.org/info/rfc8610. + + + + + + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 1] + +RFC 8610 CDDL June 2019 + + +Copyright Notice + + Copyright (c) 2019 IETF Trust and the persons identified as the + document authors. All rights reserved. + + This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with respect + to this document. Code Components extracted from this document must + include Simplified BSD License text as described in Section 4.e of + the Trust Legal Provisions and are provided without warranty as + described in the Simplified BSD License. + +Table of Contents + + 1. Introduction ....................................................4 + 1.1. Requirements Notation ......................................5 + 1.2. Terminology ................................................5 + 2. The Style of Data Structure Specification .......................5 + 2.1. Groups and Composition in CDDL .............................7 + 2.1.1. Usage ..............................................10 + 2.1.2. Syntax .............................................10 + 2.2. Types .....................................................11 + 2.2.1. Values .............................................11 + 2.2.2. Choices ............................................11 + 2.2.3. Representation Types ...............................13 + 2.2.4. Root Type ..........................................14 + 3. Syntax .........................................................15 + 3.1. General Conventions .......................................15 + 3.2. Occurrence ................................................16 + 3.3. Predefined Names for Types ................................17 + 3.4. Arrays ....................................................18 + 3.5. Maps ......................................................19 + 3.5.1. Structs ............................................19 + 3.5.2. Tables .............................................22 + 3.5.3. Non-deterministic Order ............................23 + 3.5.4. Cuts in Maps .......................................24 + 3.6. Tags ......................................................25 + 3.7. Unwrapping ................................................26 + 3.8. Controls ..................................................27 + 3.8.1. Control Operator .size .............................27 + 3.8.2. Control Operator .bits .............................28 + 3.8.3. Control Operator .regexp ...........................29 + + + + + + +Birkholz, et al. Standards Track [Page 2] + +RFC 8610 CDDL June 2019 + + + 3.8.4. Control Operators .cbor and .cborseq ...............30 + 3.8.5. Control Operators .within and .and .................30 + 3.8.6. Control Operators .lt, .le, .gt, .ge, .eq, + .ne, and .default ..................................31 + 3.9. Socket/Plug ...............................................32 + 3.10. Generics .................................................33 + 3.11. Operator Precedence ......................................34 + 4. Making Use of CDDL .............................................36 + 4.1. As a Guide for a Human User ...............................36 + 4.2. For Automated Checking of CBOR Data Structures ............36 + 4.3. For Data Analysis Tools ...................................37 + 5. Security Considerations ........................................37 + 6. IANA Considerations ............................................38 + 6.1. CDDL Control Operators Registry ...........................38 + 7. References .....................................................40 + 7.1. Normative References ......................................40 + 7.2. Informative References ....................................41 + Appendix A. Parsing Expression Grammars (PEGs) ....................43 + Appendix B. ABNF Grammar ..........................................45 + Appendix C. Matching Rules ........................................47 + Appendix D. Standard Prelude ......................................52 + Appendix E. Use with JSON .........................................53 + Appendix F. A CDDL Tool ...........................................56 + Appendix G. Extended Diagnostic Notation ..........................56 + G.1. Whitespace in Byte String Notation .........................57 + G.2. Text in Byte String Notation ...............................57 + G.3. Embedded CBOR and CBOR Sequences in Byte Strings ...........57 + G.4. Concatenated Strings .......................................58 + G.5. Hexadecimal, Octal, and Binary Numbers .....................59 + G.6. Comments ...................................................59 + Appendix H. Examples ..............................................60 + Acknowledgements ..................................................63 + Contributors ......................................................63 + Authors' Addresses ................................................64 + + + + + + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 3] + +RFC 8610 CDDL June 2019 + + +1. Introduction + + In this document, a notational convention to express Concise Binary + Object Representation (CBOR) data structures [RFC7049] is defined. + + The main goal for the convention is to provide a unified notation + that can be used when defining protocols that use CBOR. We term the + convention "Concise Data Definition Language", or CDDL. + + The CBOR notational convention has the following goals: + + (G1) Provide an unambiguous description of the overall structure of + a CBOR data item. + + (G2) Be flexible in expressing the multiple ways in which data can + be represented in the CBOR data format. + + (G3) Be able to express common CBOR datatypes and structures. + + (G4) Provide a single format that is both readable and editable for + humans and processable by a machine. + + (G5) Enable automatic checking of CBOR data items for data format + compliance. + + (G6) Enable extraction of specific elements from CBOR data for + further processing. + + Not an original goal per se, but a convenient side effect of the JSON + generic data model being a subset of the CBOR generic data model, is + the fact that CDDL can also be used for describing JSON data + structures (see Appendix E). + + This document has the following structure: + + The syntax of CDDL is defined in Section 3. Examples of CDDL and a + related CBOR data item ("instance"), some of which use the JSON form, + are described in Appendix H. Section 4 discusses usage of CDDL. + Examples are provided throughout the text to better illustrate + concept definitions. A formal definition of CDDL using ABNF grammar + [RFC5234] is provided in Appendix B. Finally, a _prelude_ of + standard CDDL definitions that is automatically prepended to, and + thus available in, every CDDL specification is listed in Appendix D. + + + + + + + + +Birkholz, et al. Standards Track [Page 4] + +RFC 8610 CDDL June 2019 + + +1.1. Requirements Notation + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and + "OPTIONAL" in this document are to be interpreted as described in + BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all + capitals, as shown here. + +1.2. Terminology + + New terms are introduced in _cursive_, which is rendered in plain + text as the new term surrounded by underscores. CDDL text in the + running text is in "typewriter", which is rendered in plain text as + the CDDL text in double quotes (double quotes are also used in the + usual English sense; the reader is expected to disambiguate this by + context). + + In this specification, the term "byte" is used in its now-customary + sense as a synonym for "octet". + +2. The Style of Data Structure Specification + + CDDL focuses on styles of specification that are in use in the + community employing the data model as pioneered by JSON and now + refined in CBOR. + + There are a number of more or less atomic elements of a CBOR data + model, such as numbers, simple values (false, true, nil), text + strings, and byte strings; CDDL does not focus on specifying their + structure. CDDL of course also allows adding a CBOR tag to a + data item. + + Beyond those atomic elements, further components of a data structure + definition language are the datatypes used for composition: arrays + and maps in CBOR (called "arrays" and "objects" in JSON). While + these are only two representation formats, they are used to specify + four loosely distinguishable styles of composition: + + o A _vector_: an array of elements that are mostly of the same + semantics. The set of signatures associated with a signed data + item is a typical application of a vector. + + o A _record_: an array the elements of which have different, + positionally defined semantics, as detailed in the data structure + definition. A 2D point, specified as an array of an x coordinate + (which comes first) and a y coordinate (coming second), is an + example of a record, as is the pair of exponent (first) and + mantissa (second) in a CBOR decimal fraction. + + + +Birkholz, et al. Standards Track [Page 5] + +RFC 8610 CDDL June 2019 + + + o A _table_: a map from a domain of map keys to a domain of map + values, that are mostly of the same semantics. A set of language + tags, each mapped to a text string translated to that specific + language, is an example of a table. The key domain is usually not + limited to a specific set by the specification but is open for the + application, e.g., in a table mapping IP addresses to Media Access + Control (MAC) addresses, the specification does not attempt to + foresee all possible IP addresses. In a language such as + JavaScript, a "Map" (as opposed to a plain "Object") would often + be employed to achieve the generality of the key domain. + + o A _struct_: a map from a domain of map keys as defined by the + specification to a domain of map values the semantics of each of + which is bound to a specific map key. This is what many people + have in mind when they think about JSON objects; CBOR adds the + ability to use map keys that are not just text strings. Structs + can be used to solve problems similar to those records are used + for; the use of explicit map keys facilitates optionality and + extensibility. + + Two important concepts provide the foundation for CDDL: + + 1. Instead of defining all four types of composition in CDDL + separately, or even defining one kind for arrays (vectors and + records) and one kind for maps (tables and structs), there is + only one kind of composition in CDDL: the _group_ (Section 2.1). + + 2. The other important concept is that of a _type_. The entire CDDL + specification defines a type (the one defined by its first + _rule_), which formally is the set of CBOR data items that are + acceptable as "instances" for this specification. CDDL + predefines a number of basic types such as "uint" (unsigned + integer) or "tstr" (text string), often making use of a simple + formal notation for CBOR data items. Each value that can be + expressed as a CBOR data item is also a type in its own right, + e.g., "1". A type can be built as a _choice_ of other types, + e.g., an "int" is either a "uint" or a "nint" (negative integer). + Finally, a type can be built as an array or a map from a group. + + The rest of this section introduces a number of basic concepts of + CDDL, and Section 3 defines additional syntax. Appendix C gives a + concise summary of the semantics of CDDL. + + + + + + + + + +Birkholz, et al. Standards Track [Page 6] + +RFC 8610 CDDL June 2019 + + +2.1. Groups and Composition in CDDL + + CDDL groups are lists of group _entries_, each of which can be a + name/value pair or a more complex group expression (which then in + turn stands for a sequence of name/value pairs). A CDDL group is a + production in a grammar that matches certain sequences of name/value + pairs but not others. The grammar is based on the concepts of + Parsing Expression Grammars (PEGs) (see Appendix A). + + In an array context, only the value of the name/value pair is + represented; the name is annotation only (and can be left off from + the group specification if not needed). In a map context, the names + become the map keys ("member keys"). + + In an array context, the actual sequence of elements in the group is + important, as that sequence is the information that allows + associating actual array elements with entries in the group. In a + map context, the sequence of entries in a group is not relevant (but + there is still a need to write down group entries in a sequence). + + An array matches a specification given as a group when the group + matches a sequence of name/value pairs the value parts of which + exactly match the elements of the array in order. + + A map matches a specification given as a group when the group matches + a sequence of name/value pairs such that all of these name/value + pairs are present in the map and the map has no name/value pair that + is not covered by the group. + + A simple example of using a group directly in a map definition is: + + person = { + age: int, + name: tstr, + employer: tstr, + } + + Figure 1: Using a Group Directly in a Map + + The three entries of the group are written between the curly braces + that create the map: here, "age", "name", and "employer" are the + names that turn into the map key text strings, and "int" and "tstr" + (text string) are the types of the map values under these keys. + + + + + + + + +Birkholz, et al. Standards Track [Page 7] + +RFC 8610 CDDL June 2019 + + + A group by itself (without creating a map around it) can be placed in + (round) parentheses and given a name by using it in a rule: + + pii = ( + age: int, + name: tstr, + employer: tstr, + ) + + Figure 2: A Basic Group + + This separate, named group definition allows us to rephrase + Figure 1 as: + + person = { + pii + } + + Figure 3: Using a Group by Name + + Note that the (curly) braces signify the creation of a map; the + groups themselves are neutral as to whether they will be used in a + map or an array. + + As shown in Figure 1, the parentheses for groups are optional when + there is some other set of brackets present. Note that they can + still be used, leading to this not-so-realistic, but perfectly valid, + example: + + person = {( + age: int, + name: tstr, + employer: tstr, + )} + + Figure 4: Using a Parenthesized Group in a Map + + + + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 8] + +RFC 8610 CDDL June 2019 + + + Groups can be used to factor out common parts of structs, e.g., + instead of writing specifications in copy/paste style, such as in + Figure 5, one can factor out the common subgroup, choose a name for + it, and write only the specific parts into the individual maps + (Figure 6). + + person = { + age: int, + name: tstr, + employer: tstr, + } + + dog = { + age: int, + name: tstr, + leash-length: float, + } + + Figure 5: Maps with Copy/Paste + + person = { + identity, + employer: tstr, + } + + dog = { + identity, + leash-length: float, + } + + identity = ( + age: int, + name: tstr, + ) + + Figure 6: Using a Group for Factorization + + Note that the lists inside the braces in the above definitions + constitute (anonymous) groups, while "identity" is a named group, + which can then be included as part of other groups (anonymous as in + the example, or themselves named). + + + + + + + + + + +Birkholz, et al. Standards Track [Page 9] + +RFC 8610 CDDL June 2019 + + +2.1.1. Usage + + Groups are the instrument used in composing data structures with + CDDL. It is a matter of style in defining those structures whether + to define groups (anonymously) right in their contexts or whether to + define them in a separate rule and to reference them with their + respective name (possibly more than once). + + With this, one is allowed to define all small parts of their data + structures and compose bigger protocol data units with those or to + have only one big protocol data unit that has all definitions ad hoc + where needed. + +2.1.2. Syntax + + The composition syntax is intended to be concise and easy to read: + + o The start and end of a group can be marked by "(" and ")". + + o Definitions of entries inside of a group are noted as follows: + _keytype => valuetype,_ (read "keytype maps to valuetype"). The + comma is actually optional (not just in the final entry), but it + is considered good style to set it. The double arrow can be + replaced by a colon in the common case of directly using a text + string or integer literal as a key; see Section 3.5.1. This is + also the common way of naming elements of an array just for + documentation; see Section 3.4. + + A basic entry consists of a _keytype_ and a _valuetype_, both of + which are types (Section 2.2); this entry matches any name/value pair + the name of which is in the keytype and the value of which is in the + valuetype. + + A group defined as a sequence of group entries matches any sequence + of name/value pairs that is composed by concatenation in order of + what the entries match. + + A group definition can also contain choices between groups; see + Section 2.2.2. + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 10] + +RFC 8610 CDDL June 2019 + + +2.2. Types + +2.2.1. Values + + Values such as numbers and strings can be used in place of a type. + (For instance, this is a very common thing to do for a key type, + common enough that CDDL provides additional convenience syntax + for this.) + + The value notation is based on the C language, but does not offer all + the syntactic variations (see Appendix B for details). The value + notation for numbers inherits from C the distinction between integer + values (no fractional part or exponent given -- NR1 [ISO6093]; + "NR" stands for "numerical representation") and floating-point values + (where a fractional part, an exponent, or both are present -- NR2 or + NR3), so the type "1" does not include any floating-point numbers + while the types "1e3" and "1.5" are both floating-point numbers and + do not include any integer numbers. + +2.2.2. Choices + + Many places that allow a type also allow a choice between types, + delimited by a "/" (slash). The entire choice construct can be put + into parentheses if this is required to make the construction + unambiguous (please see Appendix B for details of the CDDL grammar). + + Choices of values can be used to express enumerations: + + attire = "bow tie" / "necktie" / "Internet attire" + protocol = 6 / 17 + + Analogous to types, CDDL also allows choices between groups, + delimited by a "//" (double slash). Note that the "//" operator + binds much more weakly than the other CDDL operators, so each line + within "delivery" in the following example is its own alternative in + the group choice: + + address = { delivery } + + delivery = ( + street: tstr, ? number: uint, city // + po-box: uint, city // + per-pickup: true ) + + city = ( + name: tstr, zip-code: uint + ) + + + + +Birkholz, et al. Standards Track [Page 11] + +RFC 8610 CDDL June 2019 + + + A group choice matches the union of the sets of name/value pair + sequences that the alternatives in the choice can. + + For both type choices and group choices, additional alternatives can + be added to a rule later in separate rules by using "/=" and "//=", + respectively, instead of "=": + + attire /= "swimwear" + + delivery //= ( + lat: float, long: float, drone-type: tstr + ) + + It is not an error if a name is first used with a "/=" or "//=" + (there is no need to "create it" with "="). + +2.2.2.1. Ranges + + Instead of naming all the values that make up a choice, CDDL allows + building a _range_ out of two values that are in an ordering + relationship: a lower bound (first value) and an upper bound (second + value). A range can be inclusive of both bounds given (denoted by + joining two values by ".."), or it can include the lower bound and + exclude the upper bound (denoted by instead using "..."). If the + lower bound exceeds the upper bound, the resulting type is the empty + set (this behavior can be desirable when generics (Section 3.10) are + being used). + + device-address = byte + max-byte = 255 + byte = 0..max-byte ; inclusive range + first-non-byte = 256 + byte1 = 0...first-non-byte ; byte1 is equivalent to byte + + CDDL currently only allows ranges between integers (matching integer + values) or between floating-point values (matching floating-point + values). If both are needed in a type, a type choice between the two + kinds of ranges can be (clumsily) used: + + int-range = 0..10 ; only integers match + float-range = 0.0..10.0 ; only floats match + BAD-range1 = 0..10.0 ; NOT DEFINED + BAD-range2 = 0.0..10 ; NOT DEFINED + numeric-range = int-range / float-range + + (See also the control operators .lt/.ge and .le/.gt in + Section 3.8.6.) + + + + +Birkholz, et al. Standards Track [Page 12] + +RFC 8610 CDDL June 2019 + + + Note that the dot is a valid name continuation character in CDDL, so + + min..max + + is not a range expression but a single name. When using a name as + the left-hand side of a range operator, use spacing as in + + min .. max + + to separate off the range operator. + +2.2.2.2. Turning a Group into a Choice + + Some choices are built out of large numbers of values, often + integers, each of which is best given a semantic name in the + specification. Instead of naming each of these integers and then + accumulating them into a choice, CDDL allows building a choice from a + group by prefixing it with an "&" character: + + terminal-color = &basecolors + basecolors = ( + black: 0, red: 1, green: 2, yellow: 3, + blue: 4, magenta: 5, cyan: 6, white: 7, + ) + extended-color = &( + basecolors, + orange: 8, pink: 9, purple: 10, brown: 11, + ) + + As with the use of groups in arrays (Section 3.4), the member names + have only documentary value (in particular, they might be used by a + tool when displaying integers that are taken from that choice). + +2.2.3. Representation Types + + CDDL allows the specification of a data item type by referring to the + CBOR representation (specifically, to major types and additional + information; see Section 2 of [RFC7049]). How this is used should be + evident from the prelude (Appendix D): a hash mark ("#") optionally + followed by a number from 0 to 7 identifying the major type, which + then can be followed by a dot and a number specifying the additional + information. This construction specifies the set of values that can + be serialized in CBOR (i.e., "any"), by the given major type if one + is given, or by the given major type with the additional information + if both are given. Where a major type of 6 (Tag) is used, the type + of the tagged item can be specified by appending it in parentheses. + + + + + +Birkholz, et al. Standards Track [Page 13] + +RFC 8610 CDDL June 2019 + + + Note that although this notation is based on the CBOR serialization, + it is about a set of values at the data model level, e.g., "#7.25" + specifies the set of values that can be represented as half-precision + floats; it does not mandate that these values also do have to be + serialized as half-precision floats: CDDL does not provide any + language means to restrict the choice of serialization variants. + This also enables the use of CDDL with JSON, which uses a + fundamentally different way of serializing (some of) the same values. + + It may be necessary to make use of representation types outside the + prelude, e.g., a specification could start by making use of an + existing tag in a more specific way or could define a new tag not + defined in the prelude: + + my_breakfast = #6.55799(breakfast) ; cbor-any is too general! + breakfast = cereal / porridge + cereal = #6.998(tstr) + porridge = #6.999([liquid, solid]) + liquid = milk / water + milk = 0 + water = 1 + solid = tstr + +2.2.4. Root Type + + There is no special syntax to identify the root of a CDDL data + structure definition: that role is simply taken by the first rule + defined in the file. + + This is motivated by the usual top-down approach for defining data + structures, decomposing a big data structure unit into smaller parts; + however, except for the root type, there is no need to strictly + follow this sequence. + + (Note that there is no way to use a group as a root -- it must be + a type.) + + + + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 14] + +RFC 8610 CDDL June 2019 + + +3. Syntax + + In this section, the overall syntax of CDDL is shown, alongside some + examples just illustrating syntax. (The definition does not attempt + to be overly formal; refer to Appendix B for details.) + +3.1. General Conventions + + The basic syntax is inspired by ABNF [RFC5234], with the following: + + o Rules, whether they define groups or types, are defined with a + name, followed by an equals sign "=" and the actual definition + according to the respective syntactic rules of that definition. + + o A name can consist of any of the characters from the set {"A" to + "Z", "a" to "z", "0" to "9", "_", "-", "@", ".", "$"}, starting + with an alphabetic character (including "@", "_", "$") and ending + in such a character or a digit. + + * Names are case sensitive. + + * It is preferred style to start a name with a lowercase letter. + + * The hyphen is preferred over the underscore (except in a + "bareword" (Section 3.5.1), where the semantics may actually + require an underscore). + + * The period may be useful for larger specifications, to express + some module structure (as in "tcp.throughput" vs. + "udp.throughput"). + + * A number of names are predefined in the CDDL prelude, as listed + in Appendix D. + + * Rule names (types or groups) do not appear in the actual CBOR + encoding, but names used as "barewords" in member keys do. + + o Comments are started by a ";" (semicolon) character and finish at + the end of a line (LF or CRLF). + + o Except within strings, whitespace (spaces, newlines, and comments) + is used to separate syntactic elements for readability (and to + separate identifiers, range operators, or numbers that follow each + other); it is otherwise completely optional. + + o Hexadecimal numbers are preceded by "0x" (without quotes) and are + case insensitive. Similarly, binary numbers are preceded by "0b". + + + + +Birkholz, et al. Standards Track [Page 15] + +RFC 8610 CDDL June 2019 + + + o Text strings are enclosed by double quotation '"' characters. + They follow the conventions for strings as defined in Section 7 of + [RFC8259]. (ABNF users may want to note that there is no support + in CDDL for the concept of case insensitivity in text strings; if + necessary, regular expressions can be used (Section 3.8.3).) + + o Byte strings are enclosed by single quotation "'" characters and + may be prefixed by "h" or "b64". If unprefixed, the string is + interpreted as with a text string, except that single quotes must + be escaped and that the resulting UTF-8 bytes are marked as a byte + string (major type 2). If prefixed as "h" or "b64", the string is + interpreted as a sequence of pairs of hex digits (base16; see + Section 8 of [RFC4648]) or a base64(url) string (Section 4 or + Section 5 of [RFC4648]), respectively (as with the diagnostic + notation in Section 6 of [RFC7049]; cf. Appendix G.2); any + whitespace present within the string (including comments) is + ignored in the prefixed case. + + o CDDL uses UTF-8 [RFC3629] for its encoding. Processing of CDDL + does not involve Unicode normalization processes. + + Example: + + ; This is a comment + person = { g } + + g = ( + "name": tstr, + age: int, ; "age" is a bareword + ) + +3.2. Occurrence + + An optional _occurrence_ indicator can be given in front of a group + entry. It is either (1) one of the characters "?" (optional), "*" + (zero or more), or "+" (one or more) or (2) of the form n*m, where n + and m are optional unsigned integers and n is the lower limit + (default 0) and m is the upper limit (default no limit) of + occurrences. + + If no occurrence indicator is specified, the group entry is to occur + exactly once (as if 1*1 were specified). A group entry with an + occurrence indicator matches sequences of name/value pairs that are + composed by concatenating a number of sequences that the basic group + entry matches, where the number needs to be allowed by the occurrence + indicator. + + + + + +Birkholz, et al. Standards Track [Page 16] + +RFC 8610 CDDL June 2019 + + + Note that CDDL, outside any directives/annotations that could + possibly be defined, does not make any prescription as to whether + arrays or maps use definite-length or indefinite-length encoding. + That is, there is no correlation between leaving the size of an array + "open" in the spec and the fact that it is then interchanged with + definite or indefinite length. + + Please also note that CDDL can describe flexibility that the data + model of the target representation does not have. This is rather + obvious for JSON but is also relevant for CBOR: + + apartment = { + kitchen: size, + * bedroom: size, + } + size = float ; in m2 + + The previous specification does not mean that CBOR is changed to + allow using the key "bedroom" more than once. In other words, due to + the restrictions imposed by the data model, the third line pretty + much turns into: + + ? bedroom: size, + + (Occurrence indicators beyond one are still useful in maps for groups + that allow a variety of keys.) + +3.3. Predefined Names for Types + + CDDL predefines a number of names. This subsection summarizes these + names, but please see Appendix D for the exact definitions. + + The following keywords for primitive datatypes are defined: + + "bool" Boolean value (major type 7, additional information 20 + or 21). + + "uint" An unsigned integer (major type 0). + + "nint" A negative integer (major type 1). + + "int" An unsigned integer or a negative integer. + + "float16" A number representable as a half-precision float [IEEE754] + (major type 7, additional information 25). + + "float32" A number representable as a single-precision float + [IEEE754] (major type 7, additional information 26). + + + +Birkholz, et al. Standards Track [Page 17] + +RFC 8610 CDDL June 2019 + + + "float64" A number representable as a double-precision float + [IEEE754] (major type 7, additional information 27). + + "float" One of float16, float32, or float64. + + "bstr" or "bytes" A byte string (major type 2). + + "tstr" or "text" Text string (major type 3). + + (Note that there are no predefined names for arrays or maps; these + are defined with the syntax given below.) + + In addition, a number of types are defined in the prelude that are + associated with CBOR tags, such as "tdate", "bigint", "regexp", etc. + +3.4. Arrays + + Array definitions surround a group with square brackets. + + For each entry, an occurrence indicator as specified in Section 3.2 + is permitted. + + For example: + + unlimited-people = [* person] + one-or-two-people = [1*2 person] + at-least-two-people = [2* person] + person = ( + name: tstr, + age: uint, + ) + + The group "person" is defined in such a way that repeating it in the + array each time generates alternating names and ages, so these are + four valid values for a data item of type "unlimited-people": + + ["roundlet", 1047, "psychurgy", 2204, "extrarhythmical", 2231] + [] + ["aluminize", 212, "climograph", 4124] + ["penintime", 1513, "endocarditis", 4084, "impermeator", 1669, + "coextension", 865] + + + + + + + + + + +Birkholz, et al. Standards Track [Page 18] + +RFC 8610 CDDL June 2019 + + +3.5. Maps + + The syntax for specifying maps merits special attention, as well as a + number of optimizations and conveniences, as it is likely to be the + focal point of many specifications employing CDDL. While the syntax + does not strictly distinguish struct and table usage of maps, it + caters specifically to each of them. + + But first, let's reiterate a feature of CBOR that it has inherited + from JSON: the key/value pairs in CBOR maps have no fixed ordering. + (One could imagine situations where fixing the ordering may be of + use. For example, a decoder could look for values related with + integer keys 1, 3, and 7. If the order were fixed and the decoder + encounters the key 4 without having encountered key 3, it could + conclude that key 3 is not available without doing more complicated + bookkeeping. Unfortunately, neither JSON nor CBOR supports this, so + no attempt was made to support this in CDDL either.) + +3.5.1. Structs + + The "struct" usage of maps is similar to the way JSON objects are + used in many JSON applications. + + A map is defined in the same way as that for defining an array (see + Section 3.4), except for using curly braces "{}" instead of square + brackets "[]". + + An occurrence indicator as specified in Section 3.2 is permitted for + each group entry. + + The following is an example of a record with a structure embedded: + + Geography = [ + city : tstr, + gpsCoordinates : GpsCoordinates, + ] + + GpsCoordinates = { + longitude : uint, ; degrees, scaled by 10^7 + latitude : uint, ; degrees, scaled by 10^7 + } + + When encoding, the Geography record is encoded using a CBOR array + with two members (the keys for the group entries are ignored), + whereas the GpsCoordinates structure is encoded as a CBOR map with + two key/value pairs. + + + + + +Birkholz, et al. Standards Track [Page 19] + +RFC 8610 CDDL June 2019 + + + Types used in a structure can be defined in separate rules or just in + place (potentially placed inside parentheses, such as for choices). + For example: + + located-samples = { + sample-point: int, + samples: [+ float], + } + + where "located-samples" is the datatype to be used when referring to + the struct, and "sample-point" and "samples" are the keys to be used. + This is actually a complete example: an identifier that is followed + by a colon can be directly used as the text string for a member key + (we speak of a "bareword" member key), as can a double-quoted string + or a number. (When other types -- in particular, types that contain + more than one value -- are used as the types of keys, they are + followed by a double arrow; see below.) + + If a text string key does not match the syntax for an identifier (or + if the specifier just happens to prefer using double quotes), the + text string syntax can also be used in the member key position, + followed by a colon. The above example could therefore have been + written with quoted strings in the member key positions. + + More generally, types specified in ways other than those listed for + the cases described above can be used in a key-type position by + following them with a double arrow -- in particular, the double arrow + is necessary if a type is named by an identifier (which, when + followed by a colon, would be interpreted as a "bareword" and turned + into a text string). A literal text string also gives rise to a type + (which contains a single value only -- the given string), so another + form for this example is: + + located-samples = { + "sample-point" => int, + "samples" => [+ float], + } + + + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 20] + +RFC 8610 CDDL June 2019 + + + See Section 3.5.4 below for how the colon (":") shortcut described + here also adds some implied semantics. + + A better way to demonstrate the use of the double arrow may be: + + located-samples = { + sample-point: int, + samples: [+ float], + * equipment-type => equipment-tolerances, + } + equipment-type = [name: tstr, manufacturer: tstr] + equipment-tolerances = [+ [float, float]] + + The example below defines a struct with optional entries: display + name (as a text string), the name components first name and family + name (as text strings), and age information (as an unsigned integer). + + PersonalData = { + ? displayName: tstr, + NameComponents, + ? age: uint, + } + + NameComponents = ( + ? firstName: tstr, + ? familyName: tstr, + ) + + Note that the group definition for NameComponents does not generate + another map; instead, all four keys are directly in the struct built + by PersonalData. + + In this example, all key/value pairs are optional from the + perspective of CDDL. With no occurrence indicator, an entry is + mandatory. + + + + + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 21] + +RFC 8610 CDDL June 2019 + + + If the addition of more entries not specified by the current + specification is desired, one can add this possibility explicitly: + + PersonalData = { + ? displayName: tstr, + NameComponents, + ? age: uint, + * tstr => any + } + + NameComponents = ( + ? firstName: tstr, + ? familyName: tstr, + ) + + Figure 7: Personal Data: Example for Extensibility + + The CDDL tool described in Appendix F generated the following as one + acceptable instance for this specification: + + {"familyName": "agust", "antiforeignism": "pretzel", + "springbuck": "illuminatingly", "exuviae": "ephemeris", + "kilometrage": "frogfish"} + + (See Section 3.9 for one way to explicitly identify an extension + point.) + +3.5.2. Tables + + A table can be specified by defining a map with entries where the + key type allows more than just a single value; for example: + + square-roots = {* x => y} + x = int + y = float + + Here, the key in each key/value pair has datatype x (defined as int), + and the value has datatype y (defined as float). + + If the specification does not need to restrict one of x or y (i.e., + the application is free to choose per entry), it can be replaced by + the predefined name "any". + + + + + + + + + +Birkholz, et al. Standards Track [Page 22] + +RFC 8610 CDDL June 2019 + + + As another example, the following could be used as a conversion table + converting from an integer or float to a string: + + tostring = {* mynumber => tstr} + mynumber = int / float + +3.5.3. Non-deterministic Order + + While the way arrays are matched is fully determined by the PEG + formalism (see Appendix A), matching is more complicated for maps, as + maps do not have an inherent order. For each candidate name/value + pair that the PEG algorithm would try, a matching member is picked + out of the entire map. For certain group expressions, more than one + member in the map may match. Most often, this is inconsequential, as + the group expression tends to consume all matches: + + labeled-values = { + ? fritz: number, + * label => value + } + label = text + value = number + + Here, if any member with the key "fritz" is present, this will be + picked by the first entry of the group; all remaining text/number + members will be picked by the second entry (and if anything remains + unpicked, the map does not match). + + However, it is possible to construct group expressions where what is + actually picked is indeterminate, but does matter: + + do-not-do-this = { + int => int, + int => 6, + } + + When this expression is matched against "{3: 5, 4: 6}", the first + group entry might pick off the "3: 5", leaving "4: 6" for matching + the second one. Or it might pick off "4: 6", leaving nothing for the + second entry. This pathological non-determinism is caused by + specifying "more general" before "more specific" and by having a + general rule that only consumes a subset of the map key/value pairs + that it is able to match -- both tend not to occur in real-world + specifications of maps. At the time of writing, CDDL tools cannot + detect such cases automatically, and for the present version of the + CDDL specification, the specification writer is simply urged to not + write pathologically non-deterministic specifications. + + + + +Birkholz, et al. Standards Track [Page 23] + +RFC 8610 CDDL June 2019 + + + (The astute reader will be reminded of what was called "ambiguous + content models" in the Standard Generalized Markup Language (SGML) + and "non-deterministic content models" in XML. That problem is + related to the one described here, but the problem here is + specifically caused by the lack of order in maps, something that the + XML schema languages do not have to contend with. Note that + RELAX NG's "interleave" pattern handles lack of order explicitly on + the specification side, while the instances in XML always have + determinate order.) + +3.5.4. Cuts in Maps + + The extensibility idiom discussed above for structs has one problem: + + extensible-map-example = { + ? "optional-key" => int, + * tstr => any + } + + In this example, there is one optional key "optional-key", which, + when present, maps to an integer. There is also a wildcard for any + future additions. + + Unfortunately, the data item + + { "optional-key": "nonsense" } + + does match this specification: while the first entry of the group + does not match, the second one (the wildcard) does. This may very + well be desirable (e.g., if a future extension is to be allowed to + extend the type of "optional-key"), but in many cases it isn't. + + In anticipation of a more general potential feature called "cuts", + CDDL allows inserting a cut "^" into the definition of the map entry: + + extensible-map-example = { + ? "optional-key" ^ => int, + * tstr => any + } + + A cut in this position means that once the member key matches the + name part of an entry that carries a cut, other potential matches for + the key of the member that occur in later entries in the group of the + map are no longer allowed. In other words, when a group entry would + pick a key/value pair based on just a matching key, it "locks in" the + pick -- this rule applies, independently of whether the value matches + + + + + +Birkholz, et al. Standards Track [Page 24] + +RFC 8610 CDDL June 2019 + + + as well, so when it does not, the entire map fails to match. In + summary, the example above no longer matches the specification as + modified with the cut. + + Since the desire for this kind of exclusive matching is so frequent, + the ":" shortcut is actually defined to include the cut semantics. + So, the preceding example (including the cut) can be written more + simply as: + + extensible-map-example = { + ? "optional-key": int, + * tstr => any + } + + or even shorter, using a bareword for the key: + + extensible-map-example = { + ? optional-key: int, + * tstr => any + } + +3.6. Tags + + A type can make use of a CBOR tag (major type 6) by using the + representation type notation, giving #6.nnn(type) where nnn is an + unsigned integer giving the tag number and "type" is the type of the + data item being tagged. + + For example, the following line from the CDDL prelude (Appendix D) + defines "biguint" as a type name for an unsigned bignum N: + + biguint = #6.2(bstr) + + The tags defined by [RFC7049] are included in the prelude. + Additional tags registered since [RFC7049] was written need to be + added to a CDDL specification as needed; e.g., a binary Universally + Unique Identifier (UUID) tag could be referenced as "buuid" in a + specification after defining + + buuid = #6.37(bstr) + + In the following example, usage of tag 32 for URIs is optional: + + my_uri = #6.32(tstr) / tstr + + + + + + + +Birkholz, et al. Standards Track [Page 25] + +RFC 8610 CDDL June 2019 + + +3.7. Unwrapping + + The group that is used to define a map or an array can often be + reused in the definition of another map or array. Similarly, a type + defined as a tag carries an internal data item that one would like to + refer to. In these cases, it is expedient to simply use the name of + the map, array, or tag type as a handle for the group or type defined + inside it. + + The "unwrap" operator (written by preceding a name by a tilde + character "~") can be used to strip the type defined for a name by + one layer, exposing the underlying group (for maps and arrays) or + type (for tags). + + For example, an application might want to define a basic header and + an advanced header. Without unwrapping, this might be done as + follows: + + basic-header-group = ( + field1: int, + field2: text, + ) + + basic-header = [ basic-header-group ] + + advanced-header = [ + basic-header-group, + field3: bytes, + field4: number, ; as in the tagged type "time" + ] + + Unwrapping simplifies this to: + + basic-header = [ + field1: int, + field2: text, + ] + + advanced-header = [ + ~basic-header, + field3: bytes, + field4: ~time, + ] + + (Note that leaving out the first unwrap operator in the latter + example would lead to nesting the basic-header in its own array + inside the advanced-header, while, with the unwrapped basic-header, + the definition of the group inside basic-header is essentially + + + +Birkholz, et al. Standards Track [Page 26] + +RFC 8610 CDDL June 2019 + + + repeated inside advanced-header, leading to a single array. This can + be used for various applications often solved by inheritance in + programming languages. The effect of unwrapping can also be + described as "threading in" the group or type inside the referenced + type, which suggested the thread-like "~" character.) + +3.8. Controls + + A _control_ allows relating a _target_ type with a _controller_ type + via a _control operator_. + + The syntax for a control type is "target .control-operator + controller", where control operators are special identifiers prefixed + by a dot. (Note that _target_ or _controller_ might need to be + parenthesized.) + + A number of control operators are defined at this point. Further + control operators may be defined by new versions of this + specification or by registering them according to the procedures in + Section 6.1. + +3.8.1. Control Operator .size + + A ".size" control controls the size of the target in bytes by the + control type. The control is defined for text and byte strings, + where it directly controls the number of bytes in the string. It is + also defined for unsigned integers (see below). Figure 8 shows + example usage for byte strings. + + full-address = [[+ label], ip4, ip6] + ip4 = bstr .size 4 + ip6 = bstr .size 16 + label = bstr .size (1..63) + + Figure 8: Control for Size in Bytes + + When applied to an unsigned integer, the ".size" control restricts + the range of that integer by giving a maximum number of bytes that + should be needed in a computer representation of that unsigned + integer. In other words, "uint .size N" is equivalent to + "0...BYTES_N", where BYTES_N == 256**N. + + audio_sample = uint .size 3 ; 24-bit, equivalent to 0...16777216 + + Figure 9: Control for Integer Size in Bytes + + + + + + +Birkholz, et al. Standards Track [Page 27] + +RFC 8610 CDDL June 2019 + + + Note that, as with value restrictions in CDDL, this control is not a + representation constraint; a number that fits into fewer bytes can + still be represented in that form, and an inefficient implementation + could use a longer form (unless that is restricted by some format + constraints outside of CDDL, such as the rules in Section 3.9 of + [RFC7049]). + +3.8.2. Control Operator .bits + + A ".bits" control on a byte string indicates that, in the target, + only the bits numbered by a number in the control type are allowed to + be set. (Bits are counted the usual way, bit number "n" being set in + "str" meaning that "(str[n >> 3] & (1 << (n & 7))) != 0".) + Similarly, a ".bits" control on an unsigned integer "i" indicates + that for all unsigned integers "n" where "(i & (1 << n)) != 0", "n" + must be in the control type. + + tcpflagbytes = bstr .bits flags + flags = &( + fin: 8, + syn: 9, + rst: 10, + psh: 11, + ack: 12, + urg: 13, + ece: 14, + cwr: 15, + ns: 0, + ) / (4..7) ; data offset bits + + rwxbits = uint .bits rwx + rwx = &(r: 2, w: 1, x: 0) + + Figure 10: Control for What Bits Can Be Set + + The CDDL tool described in Appendix F generates the following ten + example instances for "tcpflagbytes": + + h'906d' h'01fc' h'8145' h'01b7' h'013d' h'409f' h'018e' h'c05f' + h'01fa' h'01fe' + + These examples do not illustrate that the above CDDL specification + does not explicitly specify a size of two bytes: a valid all-clear + instance of flag bytes could be "h''" or "h'00'" or even "h'000000'" + as well. + + + + + + +Birkholz, et al. Standards Track [Page 28] + +RFC 8610 CDDL June 2019 + + +3.8.3. Control Operator .regexp + + A ".regexp" control indicates that the text string given as a target + needs to match the XML Schema Definition (XSD) regular expression + given as a value in the control type. XSD regular expressions are + defined in Appendix F of [W3C.REC-xmlschema-2-20041028]. + + nai = tstr .regexp "[A-Za-z0-9]+@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)+" + + Figure 11: Control with an XSD regexp + + An example matching this regular expression: + + "N1@CH57HF.4Znqe0.dYJRN.igjf" + +3.8.3.1. Usage Considerations + + Note that XSD regular expressions do not support the usual \x or \u + escapes for hexadecimal expression of bytes or Unicode code points. + However, in CDDL the XSD regular expressions are contained in text + strings, the literal notation for which provides \u escapes; this + should suffice for most applications that use regular expressions for + text strings. (Note that this also means that there is one level of + string escaping before the XSD escaping rules are applied.) + + XSD regular expressions support character class subtraction, a + feature often not found in regular expression libraries; + specification writers may want to use this feature sparingly. + Similar considerations apply to Unicode character classes; where + these are used, the specification that employs CDDL SHOULD identify + which Unicode versions are addressed. + + Other surprises for infrequent users of XSD regular expressions may + include the following: + + o No direct support for case insensitivity. While case + insensitivity has gone mostly out of fashion in protocol design, + it is sometimes needed and then needs to be expressed manually as + in "[Cc][Aa][Ss][Ee]". + + o The support for popular character classes such as \w and \d is + based on Unicode character properties; this is often not what is + desired in an ASCII-based protocol and thus might lead to + surprises. (\s and \S do have their more conventional meanings, + and "." matches any character but the line-ending characters \r + or \n.) + + + + + +Birkholz, et al. Standards Track [Page 29] + +RFC 8610 CDDL June 2019 + + +3.8.3.2. Discussion + + There are many flavors of regular expression in use in the + programming community. For instance, Perl-Compatible Regular + Expressions (PCREs) are widely used and probably are more useful than + XSD regular expressions. However, there is no normative reference + for PCREs that could be used in the present document. Instead, we + opt for XSD regular expressions for now. There is precedent for that + choice in the IETF, e.g., in YANG [RFC7950]. + + Note that CDDL uses controls as its main extension point. This + creates the opportunity to add further regular expression formats in + addition to the one referenced here, if desired. As an example, a + proposal for a ".pcre" control is defined in [CDDL-Freezer]. + +3.8.4. Control Operators .cbor and .cborseq + + A ".cbor" control on a byte string indicates that the byte string + carries a CBOR-encoded data item. Decoded, the data item matches the + type given as the right-hand-side argument (type1 in the following + example). + + "bytes .cbor type1" + + Similarly, a ".cborseq" control on a byte string indicates that the + byte string carries a sequence of CBOR-encoded data items. When the + data items are taken as an array, the array matches the type given as + the right-hand-side argument (type2 in the following example). + + "bytes .cborseq type2" + + (The conversion of the encoded sequence to an array can be effected, + for instance, by wrapping the byte string between the two bytes 0x9f + and 0xff and decoding the wrapped byte string as a CBOR-encoded + data item.) + +3.8.5. Control Operators .within and .and + + A ".and" control on a type indicates that the data item matches both + the left-hand-side type and the type given as the right-hand side. + (Formally, the resulting type is the intersection of the two types + given.) + + "type1 .and type2" + + + + + + + +Birkholz, et al. Standards Track [Page 30] + +RFC 8610 CDDL June 2019 + + + A variant of the ".and" control is the ".within" control, which + expresses an additional intent: the left-hand-side type is meant to + be a subset of the right-hand-side type. + + "type1 .within type2" + + While both forms have the identical formal semantics (intersection), + the intention of the ".within" form is that the right-hand side gives + guidance to the types allowed on the left-hand side, which typically + is a socket (Section 3.9): + + message = $message .within message-structure + message-structure = [message_type, *message_option] + message_type = 0..255 + message_option = any + + $message /= [3, dough: text, topping: [* text]] + $message /= [4, noodles: text, sauce: text, parmesan: bool] + + For ".within", a tool might flag an error if type1 allows data items + that are not allowed by type2. In contrast, for ".and", there is no + expectation that type1 is already a subset of type2. + +3.8.6. Control Operators .lt, .le, .gt, .ge, .eq, .ne, and .default + + The controls .lt, .le, .gt, .ge, .eq, and .ne specify a constraint + on the left-hand-side type to be a value less than, less than or + equal to, greater than, greater than or equal to, equal to, or not + equal to a value given as a right-hand-side type (containing just + that single value). In the present specification, the first four + controls (.lt, .le, .gt, and .ge) are defined only for numeric types, + as these have a natural ordering relationship. + + speed = number .ge 0 ; unit: m/s + + .ne and .eq are defined for both numeric values and values of other + types. If one of the values is not of a numeric type, equality is + determined as follows: text strings are equal (satisfy .eq / do not + satisfy .ne) if they are bytewise identical; the same applies for + byte strings. Arrays are equal if they have the same number of + elements, all of which are equal pairwise in order between the + arrays. Maps are equal if they have the same number of key/value + pairs, and there is pairwise equality between the key/value pairs + between the two maps. Tagged values are equal if they both have the + same tag and the values are equal. Values of simple types match if + they are the same values. Numeric types that occur within arrays, + + + + + +Birkholz, et al. Standards Track [Page 31] + +RFC 8610 CDDL June 2019 + + + maps, or tagged values are equal if their numeric value is equal and + they are both integers or both floating-point values. All other + cases are not equal (e.g., comparing a text string with a byte + string). + + A variant of the ".ne" control is the ".default" control, which + expresses an additional intent: the value specified by the + right-hand-side type is intended as a default value for the + left-hand-side type given, and the implied .ne control is there to + prevent this value from being sent over the wire. This control is + only meaningful when the control type is used in an optional context; + otherwise, there would be no way to make use of the default value. + + timer = { + time: uint, + ? displayed-step: (number .gt 0) .default 1 + } + +3.9. Socket/Plug + + For both type choices and group choices, a mechanism is defined that + facilitates starting out with empty choices and assembling them + later, potentially in separate files that are concatenated to build + the full specification. + + Per convention, CDDL extension points are marked with a leading + dollar sign (types) or two leading dollar signs (groups). Tools + honor that convention by not raising an error if such a type or group + is not defined at all; the symbol is then taken to be an empty type + choice (group choice), i.e., no choice is available. + + tcp-header = {seq: uint, ack: uint, * $$tcp-option} + + ; later, in a different file + + $$tcp-option //= ( + sack: [+(left: uint, right: uint)] + ) + + ; and, maybe in another file + + $$tcp-option //= ( + sack-permitted: true + ) + + Names that start with a single "$" are "type sockets", starting out + as an empty type, and intended to be extended via "/=". Names that + start with a double "$$" are "group sockets", starting out as an + + + +Birkholz, et al. Standards Track [Page 32] + +RFC 8610 CDDL June 2019 + + + empty group choice, and intended to be extended via "//=". In either + case, it is not an error if there is no definition for a socket at + all; this then means there is no way to satisfy the rule (i.e., the + choice is empty). + + As a convention, all definitions (plugs) for socket names must be + augmentations, i.e., they must be using "/=" and "//=", respectively. + + To pick up the example illustrated in Figure 7, the socket/plug + mechanism could be used as shown in Figure 12: + + PersonalData = { + ? displayName: tstr, + NameComponents, + ? age: uint, + * $$personaldata-extensions + } + + NameComponents = ( + ? firstName: tstr, + ? familyName: tstr, + ) + + ; The above already works as is. + ; But then, we can add later: + + $$personaldata-extensions //= ( + favorite-salsa: tstr, + ) + + ; and again, somewhere else: + + $$personaldata-extensions //= ( + shoesize: uint, + ) + + Figure 12: Personal Data Example: Using Socket/Plug Extensibility + +3.10. Generics + + Using angle brackets, the left-hand side of a rule can add formal + parameters after the name being defined, as in: + + messages = message<"reboot", "now"> / message<"sleep", 1..100> + message<t, v> = {type: t, value: v} + + + + + + +Birkholz, et al. Standards Track [Page 33] + +RFC 8610 CDDL June 2019 + + + When using a generic rule, the formal parameters are bound to the + actual arguments supplied (also using angle brackets), within the + scope of the generic rule (as if there were a rule of the form + parameter = argument). + + Generic rules can be used for establishing names for both types and + groups. + + (At this time, there are some limitations to the nesting of generics + in the CDDL tool described in Appendix F.) + +3.11. Operator Precedence + + As with any language that has multiple syntactic features such as + prefix and infix operators, CDDL has operators that bind more tightly + than others. This is becoming more complicated than, say, in ABNF, + as CDDL has both types and groups, with operators that are specific + to these concepts. Type operators (such as "/" for type choice) + operate on types, while group operators (such as "//" for group + choice) operate on groups. Types can simply be used in groups, but + groups need to be bracketed (as arrays or maps) to become types. So, + type operators naturally bind closer than group operators. + + For instance, in + + t = [group1] + group1 = (a / b // c / d) + a = 1 b = 2 c = 3 d = 4 + + group1 is a group choice between the type choice of a and b and the + type choice of c and d. This becomes more relevant once member keys + and/or occurrences are added in: + + t = {group2} + group2 = (? ab: a / b // cd: c / d) + a = 1 b = 2 c = 3 d = 4 + + is a group choice between the optional member "ab" of type a or b and + the member "cd" of type c or d. Note that the optionality is + attached to the first choice ("ab"), not to the second choice. + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 34] + +RFC 8610 CDDL June 2019 + + + Similarly, in + + t = [group3] + group3 = (+ a / b / c) + a = 1 b = 2 c = 3 + + group3 is a repetition of a type choice between a, b, and c; if just + a is to be repeatable, a group choice is needed to focus the + occurrence: + + t = [group4] + group4 = (+ a // b / c) + a = 1 b = 2 c = 3 + + group4 is a group choice between a repeatable a and a single b or c. + + A comment has been that the semantics of group3 could be + counterintuitive. In general, as with many other languages with + operator precedence rules, the specification writer is encouraged not + to rely on them, but to insert parentheses liberally to guide readers + that are not familiar with CDDL precedence rules: + + t = [group4a] + group4a = ((+ a) // (b / c)) + a = 1 b = 2 c = 3 + + The operator precedences, in sequence of loose to tight binding, are + defined in Appendix B and summarized in Table 1. (Arities given are + 1 for unary prefix operators and 2 for binary infix operators.) + + + + + + + + + + + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 35] + +RFC 8610 CDDL June 2019 + + + +----------+-------+---------------------------+------------+ + | Operator | Arity | Operates on | Precedence | + +----------+-------+---------------------------+------------+ + | = | 2 | name = type, name = group | 1 | + | /= | 2 | name /= type | 1 | + | //= | 2 | name //= group | 1 | + | // | 2 | group // group | 2 | + | , | 2 | group, group | 3 | + | * | 1 | * group | 4 | + | n*m | 1 | n*m group | 4 | + | + | 1 | + group | 4 | + | ? | 1 | ? group | 4 | + | => | 2 | type => type | 5 | + | : | 2 | name: type | 5 | + | / | 2 | type / type | 6 | + | .. | 2 | type..type | 7 | + | ... | 2 | type...type | 7 | + | .ctrl | 2 | type .ctrl type | 7 | + | & | 1 | &group | 8 | + | ~ | 1 | ~type | 8 | + +----------+-------+---------------------------+------------+ + + Table 1: Summary of Operator Precedences + +4. Making Use of CDDL + + In this section, we discuss several potential ways to employ CDDL. + +4.1. As a Guide for a Human User + + CDDL can be used to efficiently define the layout of CBOR data, such + that a human implementer can easily see how data is supposed to be + encoded. + + Since CDDL maps parts of the CBOR data to human-readable names, tools + could be built that use CDDL to provide a human-friendly + representation of the CBOR data and allow them to edit such data + while remaining compliant with its CDDL definition. + +4.2. For Automated Checking of CBOR Data Structures + + CDDL has been specified such that a machine can handle the CDDL + definition and related CBOR data (and, thus, also JSON data). For + example, a machine could use CDDL to check whether or not CBOR data + is compliant with its definition. + + + + + + +Birkholz, et al. Standards Track [Page 36] + +RFC 8610 CDDL June 2019 + + + The need for thoroughness of such compliance checking depends on the + application. For example, an application may decide not to check the + data structure at all and use the CDDL definition solely as a means + to indicate the structure of the data to the programmer. + + On the other hand, the application may also implement a checking + mechanism that goes as far as checking that all mandatory map members + are available. + + The matter of how far the data description must be enforced by an + application is left to the designers and implementers of that + application, keeping in mind related security considerations. + + In no case is it intended that a CDDL tool would be "writing code" + for an implementation. + +4.3. For Data Analysis Tools + + In the long run, it can be expected that more and more data will be + stored using the CBOR data format. + + Where there is data, there is data analysis and the need to process + such data automatically. CDDL can be used for such automated data + processing, allowing tools to verify data, clean it, and extract + particular parts of interest from it. + + Since CBOR is designed with constrained devices in mind, a likely use + of it would be small sensors. An interesting use would thus be + automated analysis of sensor data. + +5. Security Considerations + + This document presents a content rules language for expressing CBOR + data structures. As such, it does not bring any security issues on + itself, although specifications of protocols that use CBOR naturally + need security analyses when defined. General guidelines for writing + security considerations are defined in [RFC3552] (BCP 72). + Specifications using CDDL to define CBOR structures in protocols need + to follow those guidelines. Additional topics that could be + considered in a security considerations section for a specification + that uses CDDL to define CBOR structures include the following: + + o Where could the language maybe cause confusion in a way that will + enable security issues? + + + + + + + +Birkholz, et al. Standards Track [Page 37] + +RFC 8610 CDDL June 2019 + + + o Where a CDDL matcher is part of the implementation of a system, + the security of the system ought not depend on the correctness of + the CDDL specification or CDDL implementation without any further + defenses in place. + + o Where the CDDL specification includes extension points, the impact + of extensions on the security of the system needs to be carefully + considered. + + Writers of CDDL specifications are strongly encouraged to value + clarity and transparency of the specification over its elegance. + Keep it as simple as possible while still expressing the needed data + model. + + A related observation about formal description techniques in general + that is strongly recommended to be kept in mind by writers of CDDL + specifications: just because CDDL makes it easier to handle + complexity in a specification, that does not make that complexity + somehow less bad (except maybe on the level of the humans having to + grasp the complex structure while reading the spec). + +6. IANA Considerations + +6.1. CDDL Control Operators Registry + + IANA has created a registry for control operators (Section 3.8). The + "CDDL Control Operators" registry has been created within the + "Concise Data Definition Language (CDDL)" registry. + + Each entry in the subregistry must include the name of the control + operator (by convention given with the leading dot) and a reference + to its documentation. Names must be composed of the leading dot + followed by a text string conforming to the production "id" in + Appendix B. + + + + + + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 38] + +RFC 8610 CDDL June 2019 + + + Initial entries in this registry are as follows: + + +----------+---------------+ + | Name | Documentation | + +----------+---------------+ + | .size | RFC 8610 | + | .bits | RFC 8610 | + | .regexp | RFC 8610 | + | .cbor | RFC 8610 | + | .cborseq | RFC 8610 | + | .within | RFC 8610 | + | .and | RFC 8610 | + | .lt | RFC 8610 | + | .le | RFC 8610 | + | .gt | RFC 8610 | + | .ge | RFC 8610 | + | .eq | RFC 8610 | + | .ne | RFC 8610 | + | .default | RFC 8610 | + +----------+---------------+ + + All other control operator names are Unassigned. + + The IANA policy for additions to this registry is "Specification + Required" as defined in [RFC8126] (which involves an Expert Review) + for names that do not include an internal dot and "IETF Review" for + names that do include an internal dot. The expert reviewer is + specifically instructed that other Standards Development + Organizations (SDOs) may want to define control operators that are + specific to their fields (e.g., based on a binary syntax already in + use at the SDO); the review process should strive to facilitate such + an undertaking. + + + + + + + + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 39] + +RFC 8610 CDDL June 2019 + + +7. References + +7.1. Normative References + + [ISO6093] ISO, "Information processing -- Representation of + numerical values in character strings for information + interchange", ISO 6093, 1985. + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, + DOI 10.17487/RFC2119, March 1997, + <https://www.rfc-editor.org/info/rfc2119>. + + [RFC3552] Rescorla, E. and B. Korver, "Guidelines for Writing RFC + Text on Security Considerations", BCP 72, RFC 3552, + DOI 10.17487/RFC3552, July 2003, + <https://www.rfc-editor.org/info/rfc3552>. + + [RFC3629] Yergeau, F., "UTF-8, a transformation format of + ISO 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, + November 2003, <https://www.rfc-editor.org/info/rfc3629>. + + [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data + Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, + <https://www.rfc-editor.org/info/rfc4648>. + + [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax + Specifications: ABNF", STD 68, RFC 5234, + DOI 10.17487/RFC5234, January 2008, + <https://www.rfc-editor.org/info/rfc5234>. + + [RFC7049] Bormann, C. and P. Hoffman, "Concise Binary Object + Representation (CBOR)", RFC 7049, DOI 10.17487/RFC7049, + October 2013, <https://www.rfc-editor.org/info/rfc7049>. + + [RFC7493] Bray, T., Ed., "The I-JSON Message Format", RFC 7493, + DOI 10.17487/RFC7493, March 2015, + <https://www.rfc-editor.org/info/rfc7493>. + + [RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for + Writing an IANA Considerations Section in RFCs", BCP 26, + RFC 8126, DOI 10.17487/RFC8126, June 2017, + <https://www.rfc-editor.org/info/rfc8126>. + + [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in + RFC 2119 Key Words", BCP 14, RFC 8174, + DOI 10.17487/RFC8174, May 2017, + <https://www.rfc-editor.org/info/rfc8174>. + + + +Birkholz, et al. Standards Track [Page 40] + +RFC 8610 CDDL June 2019 + + + [RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data + Interchange Format", STD 90, RFC 8259, + DOI 10.17487/RFC8259, December 2017, + <https://www.rfc-editor.org/info/rfc8259>. + + [W3C.REC-xmlschema-2-20041028] + Biron, P. and A. Malhotra, "XML Schema Part 2: Datatypes + Second Edition", World Wide Web Consortium Recommendation + REC-xmlschema-2-20041028, October 2004, + <https://www.w3.org/TR/2004/REC-xmlschema-2-20041028>. + +7.2. Informative References + + [CDDL-Freezer] + Bormann, C., "A feature freezer for the Concise Data + Definition Language (CDDL)", Work in Progress, + draft-bormann-cbor-cddl-freezer-01, August 2018. + + [GRASP] Bormann, C., Carpenter, B., Ed., and B. Liu, Ed., "A + Generic Autonomic Signaling Protocol (GRASP)", Work in + Progress, draft-ietf-anima-grasp-15, July 2017. + + [IEEE754] IEEE, "IEEE Standard for Floating-Point Arithmetic", IEEE + Std 754-2008. + + [JCR] Newton, A. and P. Cordell, "A Language for Rules + Describing JSON Content", Work in Progress, + draft-newton-json-content-rules-09, September 2017. + + [PEG] Ford, B., "Parsing expression grammars: a recognition- + based syntactic foundation", Proceedings of the 31st ACM + SIGPLAN-SIGACT symposium on Principles of programming + languages - POPL '04, DOI 10.1145/964001.964011, + January 2004. + + [RELAXNG] ISO/IEC, "Information technology -- Document Schema + Definition Language (DSDL) -- Part 2: Regular-grammar- + based validation -- RELAX NG", ISO/IEC 19757-2, + December 2008. + + [RFC7071] Borenstein, N. and M. Kucherawy, "A Media Type for + Reputation Interchange", RFC 7071, DOI 10.17487/RFC7071, + November 2013, <https://www.rfc-editor.org/info/rfc7071>. + + [RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language", + RFC 7950, DOI 10.17487/RFC7950, August 2016, + <https://www.rfc-editor.org/info/rfc7950>. + + + + +Birkholz, et al. Standards Track [Page 41] + +RFC 8610 CDDL June 2019 + + + [RFC8007] Murray, R. and B. Niven-Jenkins, "Content Delivery Network + Interconnection (CDNI) Control Interface / Triggers", + RFC 8007, DOI 10.17487/RFC8007, December 2016, + <https://www.rfc-editor.org/info/rfc8007>. + + [RFC8152] Schaad, J., "CBOR Object Signing and Encryption (COSE)", + RFC 8152, DOI 10.17487/RFC8152, July 2017, + <https://www.rfc-editor.org/info/rfc8152>. + + [RFC8428] Jennings, C., Shelby, Z., Arkko, J., Keranen, A., and C. + Bormann, "Sensor Measurement Lists (SenML)", RFC 8428, + DOI 10.17487/RFC8428, August 2018, + <https://www.rfc-editor.org/info/rfc8428>. + + [YAML] Ben-Kiki, O., Evans, C., and I. Net, "YAML Ain't Markup + Language (YAML[TM]) Version 1.2", 3rd Edition, + October 2009, <https://yaml.org/spec/1.2/spec.html>. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 42] + +RFC 8610 CDDL June 2019 + + +Appendix A. Parsing Expression Grammars (PEGs) + + This appendix is normative. + + Since the 1950s, many grammar notations are based on Backus-Naur Form + (BNF), a notation for context-free grammars (CFGs) within Chomsky's + generative system of grammars. The Augmented Backus-Naur Form (ABNF) + [RFC5234], widely used in IETF specifications and also inspiring the + syntax of CDDL, is an example of this. + + Generative grammars can express ambiguity well, but this very + property may make them hard to use in recognition systems, spawning a + number of subdialects that pose constraints on generative grammars to + be used with parser generators; this scenario may be hard for the + specification writer to manage. + + PEGs [PEG] provide an alternative formal foundation for describing + grammars that emphasizes recognition over generation and resolves + what would have been ambiguity in generative systems by introducing + the concept of "prioritized choice". + + The notation for PEGs is quite close to BNF, with the usual "Extended + BNF" features, such as repetition, added. However, where BNF uses + the unordered (symmetrical) choice operator "|" (incidentally notated + as "/" in ABNF), PEG provides a prioritized choice operator "/". The + two alternatives listed are to be tested in left-to-right order, + locking in the first successful match and disregarding any further + potential matches within the choice (but not disabling alternatives + in choices containing this choice, as a cut (Section 3.5.4) would). + + For example, the ABNF expressions + + A = "a" "b" / "a" (1) + + and + + A = "a" / "a" "b" (2) + + are equivalent in ABNF's original generative framework but are very + different in PEG: in (2), the second alternative will never match, as + any input string starting with an "a" will already succeed in the + first alternative, locking in the match. + + Similarly, the occurrence indicators ("?", "*", "+") are "greedy" in + PEG, i.e., they consume as much input as they match (and, as a + consequence, "a* a" in PEG notation or "*a a" in CDDL syntax never + can match anything, as all input matching "a" is already consumed by + the initial "a*", leaving nothing to match the second "a"). + + + +Birkholz, et al. Standards Track [Page 43] + +RFC 8610 CDDL June 2019 + + + Incidentally, the grammar of CDDL itself, as written in ABNF in + Appendix B, can be interpreted both (1) in the generative framework + on which RFC 5234 is based and (2) as a PEG. This was made possible + by ordering the choices in the grammar such that a successful match + made on the left-hand side of a "/" operator is always the intended + match, instead of relying on the power of symmetrical choices (for + example, note the sequence of alternatives in the rule for "uint", + where the lone zero is behind the longer match alternatives that + start with a zero). + + The syntax used for expressing the PEG component of CDDL is based on + ABNF, interpreted in the obvious way with PEG semantics. The ABNF + convention of notating occurrence indicators before the controlled + primary, and of allowing numeric values for minimum and maximum + occurrence around a "*" sign, is copied. While PEG is only about + characters, CDDL has a richer set of elements, such as types and + groups. Specifically, the following constructs map: + + +-------+-------+-------------------------------------------+ + | CDDL | PEG | Remark | + +-------+-------+-------------------------------------------+ + | "=" | "<-" | /= and //= are abbreviations | + | "//" | "/" | prioritized choice | + | "/" | "/" | prioritized choice, limited to types only | + | "?" P | P "?" | zero or one | + | "*" P | P "*" | zero or more | + | "+" P | P "+" | one or more | + | A B | A B | sequence | + | A, B | A B | sequence, comma is decoration only | + +-------+-------+-------------------------------------------+ + + The literal notation and the use of square brackets, curly braces, + tildes, ampersands, and hash marks are specific to CDDL and unrelated + to the conventional PEG notation. The DOT (".") from PEG is replaced + by the unadorned "#" or its alias "any". Also, CDDL does not provide + the syntactic predicate operators NOT ("!") or AND ("&") from PEG, + reducing expressiveness as well as complexity. + + For more details about PEG's theoretical foundation and interesting + properties of the operators such as associativity and distributivity, + the reader is referred to [PEG]. + + + + + + + + + + +Birkholz, et al. Standards Track [Page 44] + +RFC 8610 CDDL June 2019 + + +Appendix B. ABNF Grammar + + This appendix is normative. + + The following is a formal definition of the CDDL syntax in ABNF + [RFC5234]. Note that, as is defined in ABNF, the quote-delimited + strings below are case insensitive (while string values and names are + case sensitive in CDDL). + + cddl = S 1*(rule S) + rule = typename [genericparm] S assignt S type + / groupname [genericparm] S assigng S grpent + + typename = id + groupname = id + + assignt = "=" / "/=" + assigng = "=" / "//=" + + genericparm = "<" S id S *("," S id S ) ">" + genericarg = "<" S type1 S *("," S type1 S ) ">" + + type = type1 *(S "/" S type1) + + type1 = type2 [S (rangeop / ctlop) S type2] + ; space may be needed before the operator if type2 ends in a name + + type2 = value + / typename [genericarg] + / "(" S type S ")" + / "{" S group S "}" + / "[" S group S "]" + / "~" S typename [genericarg] + / "&" S "(" S group S ")" + / "&" S groupname [genericarg] + / "#" "6" ["." uint] "(" S type S ")" + / "#" DIGIT ["." uint] ; major/ai + / "#" ; any + + rangeop = "..." / ".." + + ctlop = "." id + + group = grpchoice *(S "//" S grpchoice) + + grpchoice = *(grpent optcom) + + + + + +Birkholz, et al. Standards Track [Page 45] + +RFC 8610 CDDL June 2019 + + + grpent = [occur S] [memberkey S] type + / [occur S] groupname [genericarg] ; preempted by above + / [occur S] "(" S group S ")" + + memberkey = type1 S ["^" S] "=>" + / bareword S ":" + / value S ":" + + bareword = id + + optcom = S ["," S] + + occur = [uint] "*" [uint] + / "+" + / "?" + + uint = DIGIT1 *DIGIT + / "0x" 1*HEXDIG + / "0b" 1*BINDIG + / "0" + + value = number + / text + / bytes + + int = ["-"] uint + + ; This is a float if it has fraction or exponent; int otherwise + number = hexfloat / (int ["." fraction] ["e" exponent ]) + hexfloat = ["-"] "0x" 1*HEXDIG ["." 1*HEXDIG] "p" exponent + fraction = 1*DIGIT + exponent = ["+"/"-"] 1*DIGIT + + text = %x22 *SCHAR %x22 + SCHAR = %x20-21 / %x23-5B / %x5D-7E / %x80-10FFFD / SESC + SESC = "\" (%x20-7E / %x80-10FFFD) + + bytes = [bsqual] %x27 *BCHAR %x27 + BCHAR = %x20-26 / %x28-5B / %x5D-10FFFD / SESC / CRLF + bsqual = "h" / "b64" + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 46] + +RFC 8610 CDDL June 2019 + + + id = EALPHA *(*("-" / ".") (EALPHA / DIGIT)) + ALPHA = %x41-5A / %x61-7A + EALPHA = ALPHA / "@" / "_" / "$" + DIGIT = %x30-39 + DIGIT1 = %x31-39 + HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" + BINDIG = %x30-31 + + S = *WS + WS = SP / NL + SP = %x20 + NL = COMMENT / CRLF + COMMENT = ";" *PCHAR CRLF + PCHAR = %x20-7E / %x80-10FFFD + CRLF = %x0A / %x0D.0A + + Figure 13: CDDL ABNF + + Note that this ABNF does not attempt to reflect the detailed rules of + what can be in a prefixed byte string. + +Appendix C. Matching Rules + + This appendix is normative. + + In this appendix, we go through the ABNF syntax rules defined in + Appendix B and briefly describe the matching semantics of each + syntactic feature. In this context, an instance (data item) + "matches" a CDDL specification if it is allowed by the CDDL + specification; this is then broken down into parts of specifications + (type and group expressions) and parts of instances (data items). + + cddl = S 1*(rule S) + + A CDDL specification is a sequence of one or more rules. Each rule + gives a name to a right-hand-side expression, either a CDDL type or a + CDDL group. Rule names can be used in the rule itself and/or other + rules (and tools can output warnings if that is not the case). The + order of the rules is significant only in two cases: + + 1. The first rule defines the semantics of the entire specification; + hence, there is no need to give that root rule a special name or + special syntax in the language (as, for example, with "start" in + RELAX NG); its name can therefore be chosen to be descriptive. + (As with all other rule names, the name of the initial rule may + be used in itself or in other rules.) + + + + + +Birkholz, et al. Standards Track [Page 47] + +RFC 8610 CDDL June 2019 + + + 2. Where a rule contributes to a type or group choice (using "/=" or + "//="), that choice is populated in the order the rules are + given; see below. + + rule = typename [genericparm] S assignt S type + / groupname [genericparm] S assigng S grpent + + typename = id + groupname = id + + A rule defines a name for a type expression (production "type") or + for a group expression (production "grpent"), with the intention that + the semantics does not change when the name is replaced by its + (parenthesized if needed) definition. Note that whether the name + defined by a rule stands for a type or a group isn't always + determined by syntax alone: e.g., "a = b" can make "a" a type if "b" + is a type, or a group if "b" is a group. More subtly, in "a = (b)", + "a" may be used as a type if "b" is a type, or as a group both when + "b" is a group and when "b" is a type (a good convention to make the + latter case stand out to the human reader is to write "a = (b,)"). + (Note that the same dual meaning of parentheses applies within an + expression but often can be resolved by the context of the + parenthesized expression. On the more general point, it may not be + clear immediately either whether "b" stands for a group or a type -- + this semantic processing may need to span several levels of rule + definitions before a determination can be made.) + + assignt = "=" / "/=" + assigng = "=" / "//=" + + A plain equals sign defines the rule name as the equivalent of the + expression to the right; it is an error if the name was already + defined with a different expression. A "/=" or "//=" extends a named + type or a group by additional choices; a number of these could be + replaced by collecting all the right-hand sides and creating a single + rule with a type choice or a group choice built from the right-hand + sides in the order of the rules given. (It is not an error to extend + a rule name that has not yet been defined; this makes the right-hand + side the first entry in the choice being created.) + + genericparm = "<" S id S *("," S id S ) ">" + genericarg = "<" S type1 S *("," S type1 S ) ">" + + Rule names can have generic parameters, which cause temporary + assignments within the right-hand sides to the parameter names from + the arguments given when citing the rule name. + + type = type1 *(S "/" S type1) + + + +Birkholz, et al. Standards Track [Page 48] + +RFC 8610 CDDL June 2019 + + + A type can be given as a choice between one or more types. The + choice matches a data item if the data item matches any one of the + types given in the choice. The choice uses PEG semantics as + discussed in Appendix A: the first choice that matches wins. (As a + result, the order of rules that contribute to a single rule name can + very well matter.) + + type1 = type2 [S (rangeop / ctlop) S type2] + + Two types can be combined with a range operator (see below) or a + control operator (see Section 3.8). + + type2 = value + + A type can be just a single value (such as 1 or "icecream" or + h'0815'), which matches only a data item with that specific value (no + conversions defined), + + / typename [genericarg] + + or be defined by a rule giving a meaning to a name (possibly after + supplying generic arguments as required by the generic parameters), + + / "(" S type S ")" + + or be defined in a parenthesized type expression (parentheses may be + necessary to override some operator precedence), or + + / "{" S group S "}" + + a map expression, which matches a valid CBOR map the key/value pairs + of which can be ordered in such a way that the resulting sequence + matches the group expression, or + + / "[" S group S "]" + + an array expression, which matches a CBOR array the elements of which + -- when taken as values and complemented by a wildcard (matches + anything) key each -- match the group, or + + / "~" S typename [genericarg] + + an "unwrapped" group (see Section 3.7), which matches the group + inside a type defined as a map or an array by wrapping the group, or + + / "&" S "(" S group S ")" + / "&" S groupname [genericarg] + + + + +Birkholz, et al. Standards Track [Page 49] + +RFC 8610 CDDL June 2019 + + + an enumeration expression, which matches any value that is within the + set of values that the values of the group given can take, or + + / "#" "6" ["." uint] "(" S type S ")" + + a tagged data item, tagged with the "uint" given and containing the + type given as the tagged value, or + + / "#" DIGIT ["." uint] ; major/ai + + a data item of a major type (given by the DIGIT), optionally + constrained to the additional information given by the uint, or + + / "#" ; any + + any data item. + + rangeop = "..." / ".." + + A range operator can be used to join two type expressions that stand + for either two integer values or two floating-point values; it + matches any value that is between the two values, where the first + value is always included in the matching set and the second value is + included for ".." and excluded for "...". + + ctlop = "." id + + A control operator ties a _target_ type to a _controller_ type as + defined in Section 3.8. Note that control operators are an extension + point for CDDL; additional documents may want to define additional + control operators. + + group = grpchoice *(S "//" S grpchoice) + + A group matches any sequence of key/value pairs that matches any of + the choices given (again using PEG semantics). + + grpchoice = *(grpent optcom) + + Each of the component groups is given as a sequence of group entries. + For a match, the sequence of key/value pairs given needs to match the + sequence of group entries in the sequence given. + + grpent = [occur S] [memberkey S] type + + A group entry can be given by a value type, which needs to be matched + by the value part of a single element; and, optionally, a memberkey + type, which needs to be matched by the key part of the element, if + + + +Birkholz, et al. Standards Track [Page 50] + +RFC 8610 CDDL June 2019 + + + the memberkey is given. If the memberkey is not given, the entry can + only be used for matching arrays, not for maps. (See below for how + that is modified by the occurrence indicator.) + + / [occur S] groupname [genericarg] ; preempted by above + + A group entry can be built from a named group, or + + / [occur S] "(" S group S ")" + + from a parenthesized group, again with a possible occurrence + indicator. + + memberkey = type1 S ["^" S] "=>" + / bareword S ":" + / value S ":" + + Key types can be given by a type expression, a bareword (which stands + for a type that just contains a string value created from this + bareword), or a value (which stands for a type that just contains + this value). A key value matches its key type if the key value is a + member of the key type, unless a cut preceding it in the group + applies (see Section 3.5.4 for how map matching is influenced by the + presence of the cuts denoted by "^" or ":" in previous entries). + + bareword = id + + A bareword is an alternative way to write a type with a single text + string value; it can only be used in the syntactic context given + above. + + optcom = S ["," S] + + (Optional commas do not influence the matching.) + + occur = [uint] "*" [uint] + / "+" + / "?" + + An occurrence indicator modifies the group given to its right by + requiring the group to match the sequence to be matched exactly for a + certain number of times (see Section 3.2) in sequence, i.e., it acts + as a (possibly infinite) group choice that contains choices with the + group repeated each of the occurrences times. + + + + + + + +Birkholz, et al. Standards Track [Page 51] + +RFC 8610 CDDL June 2019 + + + The rest of the ABNF describes syntax for value notation that should + be familiar to readers from programming languages, with the possible + exception of h'..' and b64'..' for byte strings, as well as syntactic + elements such as comments and line ends. + +Appendix D. Standard Prelude + + This appendix is normative. + + The following prelude is automatically added to each CDDL file. + (Note that technically, it is a postlude, as it does not disturb the + selection of the first rule as the root of the definition.) + + any = # + + uint = #0 + nint = #1 + int = uint / nint + + bstr = #2 + bytes = bstr + tstr = #3 + text = tstr + + tdate = #6.0(tstr) + time = #6.1(number) + number = int / float + biguint = #6.2(bstr) + bignint = #6.3(bstr) + bigint = biguint / bignint + integer = int / bigint + unsigned = uint / biguint + decfrac = #6.4([e10: int, m: integer]) + bigfloat = #6.5([e2: int, m: integer]) + eb64url = #6.21(any) + eb64legacy = #6.22(any) + eb16 = #6.23(any) + encoded-cbor = #6.24(bstr) + uri = #6.32(tstr) + b64url = #6.33(tstr) + b64legacy = #6.34(tstr) + regexp = #6.35(tstr) + mime-message = #6.36(tstr) + cbor-any = #6.55799(any) + + + + + + + +Birkholz, et al. Standards Track [Page 52] + +RFC 8610 CDDL June 2019 + + + float16 = #7.25 + float32 = #7.26 + float64 = #7.27 + float16-32 = float16 / float32 + float32-64 = float32 / float64 + float = float16-32 / float64 + + false = #7.20 + true = #7.21 + bool = false / true + nil = #7.22 + null = nil + undefined = #7.23 + + Figure 14: CDDL Prelude + + Note that the prelude is deemed to be fixed. This means, for + instance, that additional tags beyond those defined in [RFC7049], as + registered, need to be defined in each CDDL file that is using them. + + A common stumbling point is that the prelude does not define a type + "string". CBOR has byte strings ("bytes" in the prelude) and text + strings ("text"), so a type that is simply called "string" would be + ambiguous. + +Appendix E. Use with JSON + + This appendix is normative. + + The JSON generic data model (implicit in [RFC8259]) is a subset of + the generic data model of CBOR. So, one can use CDDL with JSON by + limiting oneself to what can be represented in JSON. Roughly + speaking, this means leaving out byte strings, tags, and simple + values other than "false", "true", and "null", leading to the + following limited prelude: + + + + + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 53] + +RFC 8610 CDDL June 2019 + + + any = # + + uint = #0 + nint = #1 + int = uint / nint + + tstr = #3 + text = tstr + + number = int / float + + float16 = #7.25 + float32 = #7.26 + float64 = #7.27 + float16-32 = float16 / float32 + float32-64 = float32 / float64 + float = float16-32 / float64 + + false = #7.20 + true = #7.21 + bool = false / true + nil = #7.22 + null = nil + + Figure 15: JSON-Compatible Subset of CDDL Prelude + + (The major types given here do not have a direct meaning in JSON, but + they can be interpreted as CBOR major types translated through + Section 4 of [RFC7049].) + + There are a few fine points in using CDDL with JSON. First, JSON + does not distinguish between integers and floating-point numbers; + there is only one kind of number (which may happen to be integral). + In this context, specifying a type as "uint", "nint", or "int" then + becomes a predicate that the number be integral. As an example, this + means that the following JSON numbers are all matching "uint": + + 10 10.0 1e1 1.0e1 100e-1 + + (The fact that these are all integers may be surprising to users + accustomed to the long tradition in programming languages of using + decimal points or exponents in a number to indicate a floating-point + literal.) + + CDDL distinguishes the various CBOR number types, but there is only + one number type in JSON. The effect of specifying a floating-point + precision (float16/float32/float64) is only to restrict the set of + + + + +Birkholz, et al. Standards Track [Page 54] + +RFC 8610 CDDL June 2019 + + + permissible values to those expressible with binary16/binary32/ + binary64; this is unlikely to be very useful when using CDDL for + specifying JSON data structures. + + Fundamentally, the number system of JSON itself is based on decimal + numbers and decimal fractions and does not have limits to its + precision or range. In practice, JSON numbers are often parsed into + a number type that is called "float64" here, creating a number of + limitations to the generic data model [RFC7493]. In particular, this + means that integers can only be expressed with interoperable + exactness when they lie in the range [-(2**53)+1, (2**53)-1] -- a + smaller range than that covered by CDDL "int". + + JSON applications that want to stay compatible with I-JSON ("Internet + JSON"; see [RFC7493]) may therefore want to define integer types with + more limited ranges, such as in Figure 16. Note that the types given + here are not part of the prelude; they need to be copied into the + CDDL specification if needed. + + ij-uint = 0..9007199254740991 + ij-nint = -9007199254740991..-1 + ij-int = -9007199254740991..9007199254740991 + + Figure 16: I-JSON Types for CDDL (Not Part of Prelude) + + JSON applications that do not need to stay compatible with I-JSON and + that actually may need to go beyond the 64-bit unsigned and negative + integers supported by "int" (= "uint"/"nint") may want to use the + following additional types from the standard prelude, which are + expressed in terms of tags but can straightforwardly be mapped into + JSON (but not I-JSON) numbers: + + biguint = #6.2(bstr) + bignint = #6.3(bstr) + bigint = biguint / bignint + integer = int / bigint + unsigned = uint / biguint + + CDDL at this point does not have a way to express the unlimited + floating-point precision that is theoretically possible with JSON; at + the time of writing, this is rarely used in protocols in practice. + + Note that a data model described in CDDL is always restricted by what + can be expressed in the serialization; e.g., floating-point values + such as NaN (not a number) and the infinities cannot be represented + in JSON even if they are allowed in the CDDL generic data model. + + + + + +Birkholz, et al. Standards Track [Page 55] + +RFC 8610 CDDL June 2019 + + +Appendix F. A CDDL Tool + + This appendix is for information only. + + A rough CDDL tool is available. For CDDL specifications, it can + check the syntax, generate one or more instances (expressed in CBOR + diagnostic notation or in pretty-printed JSON), and validate an + existing instance against the specification: + + Usage: + cddl spec.cddl generate [n] + cddl spec.cddl json-generate [n] + cddl spec.cddl validate instance.cbor + cddl spec.cddl validate instance.json + + Figure 17: CDDL Tool Usage + + Install on a system with a modern Ruby via: + + gem install cddl + + Figure 18: CDDL Tool Installation + + The accompanying CBOR diagnostic tools (which are automatically + installed by the above) are described in <https://github.com/cabo/ + cbor-diag>; they can be used to convert between binary CBOR, a + pretty-printed hexadecimal form of binary CBOR, CBOR diagnostic + notation, JSON, and YAML [YAML]. + +Appendix G. Extended Diagnostic Notation + + This appendix is normative. + + Section 6 of [RFC7049] defines a "diagnostic notation" in order to be + able to converse about CBOR data items without having to resort to + binary data. Diagnostic notation is based on JSON, with extensions + for representing CBOR constructs such as binary data and tags. + + (Standardizing this together with the actual interchange format does + not serve to create another interchange format but enables the use of + a shared diagnostic notation in tools for and documents about CBOR.) + + This appendix discusses a few extensions to the diagnostic notation + that have turned out to be useful since RFC 7049 was written. We + refer to the result as Extended Diagnostic Notation (EDN). + + + + + + +Birkholz, et al. Standards Track [Page 56] + +RFC 8610 CDDL June 2019 + + +G.1. Whitespace in Byte String Notation + + Examples often benefit from some whitespace (spaces, line breaks) in + byte strings. In EDN, whitespace is ignored in prefixed byte + strings; for instance, the following are equivalent: + + h'48656c6c6f20776f726c64' + h'48 65 6c 6c 6f 20 77 6f 72 6c 64' + h'4 86 56c 6c6f + 20776 f726c64' + +G.2. Text in Byte String Notation + + Diagnostic notation notates byte strings in one of the base encodings + per [RFC4648], enclosed in single quotes, prefixed by >h< for base16, + >b32< for base32, >h32< for base32hex, or >b64< for base64 or + base64url. Quite often, byte strings carry bytes that are + meaningfully interpreted as UTF-8 text. EDN allows the use of single + quotes without a prefix to express byte strings with UTF-8 text; for + instance, the following are equivalent: + + 'hello world' + h'68656c6c6f20776f726c64' + + The escaping rules of JSON strings are applied equivalently for + text-based byte strings, e.g., "\" stands for a single backslash and + "'" stands for a single quote. Whitespace is included literally, + i.e., the previous section does not apply to text-based byte strings. + +G.3. Embedded CBOR and CBOR Sequences in Byte Strings + + Where a byte string is to carry an embedded CBOR-encoded item, or + more generally a sequence of zero or more such items, the diagnostic + notation for these zero or more CBOR data items, separated by commas, + can be enclosed in << and >> to notate the byte string resulting from + encoding the data items and concatenating the result. For instance, + each pair of columns in the following are equivalent: + + <<1>> h'01' + <<1, 2>> h'0102' + <<"foo", null>> h'63666F6FF6' + <<>> h'' + + + + + + + + + +Birkholz, et al. Standards Track [Page 57] + +RFC 8610 CDDL June 2019 + + +G.4. Concatenated Strings + + While the ability to include whitespace enables line-breaking of + encoded byte strings, a mechanism is needed to be able to include + text strings as well as byte strings in direct UTF-8 representation + into line-based documents (such as RFCs and source code). + + We extend the diagnostic notation by allowing multiple text strings + or multiple byte strings to be notated separated by whitespace; these + are then concatenated into a single text or byte string, + respectively. Text strings and byte strings do not mix within such a + concatenation, except that byte string notation can be used inside a + sequence of concatenated text string notation to encode characters + that may be better represented in an encoded way. The following four + values are equivalent: + + "Hello world" + "Hello " "world" + "Hello" h'20' "world" + "" h'48656c6c6f20776f726c64' "" + + Similarly, the following byte string values are equivalent: + + 'Hello world' + 'Hello ' 'world' + 'Hello ' h'776f726c64' + 'Hello' h'20' 'world' + '' h'48656c6c6f20776f726c64' '' b64'' + h'4 86 56c 6c6f' h' 20776 f726c64' + + (Note that the approach of separating by whitespace, while familiar + from the C language, requires some attention -- a single comma makes + a big difference here.) + + + + + + + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 58] + +RFC 8610 CDDL June 2019 + + +G.5. Hexadecimal, Octal, and Binary Numbers + + In addition to JSON's decimal numbers, EDN provides hexadecimal, + octal, and binary numbers in the usual C-language notation (octal + with 0o prefix present only). + + The following are equivalent: + + 4711 + 0x1267 + 0o11147 + 0b1001001100111 + + As are: + + 1.5 + 0x1.8p0 + 0x18p-4 + +G.6. Comments + + Longer pieces of diagnostic notation may benefit from comments. JSON + famously does not provide for comments, and basic diagnostic notation + per RFC 7049 inherits this property. + + In EDN, comments can be included, delimited by slashes ("/"). Any + text within and including a pair of slashes is considered a comment. + + Comments are considered whitespace. Hence, they are allowed in + prefixed byte strings; for instance, the following are equivalent: + + h'68656c6c6f20776f726c64' + h'68 65 6c /doubled l!/ 6c 6f /hello/ + 20 /space/ + 77 6f 72 6c 64' /world/ + + This can be used to annotate a CBOR structure as in: + + /grasp-message/ [/M_DISCOVERY/ 1, /session-id/ 10584416, + /objective/ [/objective-name/ "opsonize", + /D, N, S/ 7, /loop-count/ 105]] + + (There are currently no end-of-line comments. If we want to add + them, "//" sounds like a reasonable delimiter given that we already + use slashes for comments, but we could also go, for example, + for "#".) + + + + + +Birkholz, et al. Standards Track [Page 59] + +RFC 8610 CDDL June 2019 + + +Appendix H. Examples + + This appendix is for information only. + + This appendix contains a few examples of structures defined + using CDDL. The theme for the examples is taken from [RFC7071], + which defines certain JSON structures in English. For a similar + example, it may also be of interest to examine Appendix A of + [RFC8007], which contains a CDDL definition for a JSON structure + defined in the main body of that RFC. + + These examples all happen to describe data that is interchanged in + JSON. Examples for CDDL definitions of data that is interchanged in + CBOR can be found in [RFC8152], [GRASP], and [RFC8428]. + + [RFC7071] defines the "reputon" structure for JSON using somewhat + formalized English text. Here is a (somewhat verbose) equivalent + definition using the same terms, but notated in CDDL: + + reputation-object = { + reputation-context, + reputon-list + } + + reputation-context = ( + application: text + ) + + reputon-list = ( + reputons: reputon-array + ) + + reputon-array = [* reputon] + + reputon = { + rater-value, + assertion-value, + rated-value, + rating-value, + ? conf-value, + ? normal-value, + ? sample-value, + ? gen-value, + ? expire-value, + * ext-value, + } + + + + + +Birkholz, et al. Standards Track [Page 60] + +RFC 8610 CDDL June 2019 + + + rater-value = ( rater: text ) + assertion-value = ( assertion: text ) + rated-value = ( rated: text ) + rating-value = ( rating: float16 ) + conf-value = ( confidence: float16 ) + normal-value = ( normal-rating: float16 ) + sample-value = ( sample-size: uint ) + gen-value = ( generated: uint ) + expire-value = ( expires: uint ) + ext-value = ( text => any ) + + An equivalent, more compact form of this example would be: + + reputation-object = { + application: text + reputons: [* reputon] + } + + reputon = { + rater: text + assertion: text + rated: text + rating: float16 + ? confidence: float16 + ? normal-rating: float16 + ? sample-size: uint + ? generated: uint + ? expires: uint + * text => any + } + + Note how this rather clearly delineates the structure somewhat + shrouded by so many words in Section 6.2.2 of [RFC7071]. Also, this + definition makes it clear that several ext-values are allowed (by + definition with different member names); RFC 7071 could be read to + forbid the repetition of ext-value ("A specific reputon-element + MUST NOT appear more than once" is ambiguous). + + + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 61] + +RFC 8610 CDDL June 2019 + + + The CDDL tool described in Appendix F generates as one example: + + { + "application": "conchometry", + "reputons": [ + { + "rater": "Ephthianura", + "assertion": "codding", + "rated": "sphaerolitic", + "rating": 0.34133473256800795, + "confidence": 0.9481983064298332, + "expires": 1568, + "unplaster": "grassy" + }, + { + "rater": "nonchargeable", + "assertion": "raglan", + "rated": "alienage", + "rating": 0.5724646875815566, + "sample-size": 3514, + "Aldebaran": "unchurched", + "puruloid": "impersonable", + "uninfracted": "pericarpoidal", + "schorl": "Caro" + }, + { + "rater": "precollectable", + "assertion": "Merat", + "rated": "thermonatrite", + "rating": 0.19164006323936977, + "confidence": 0.6065252103391268, + "normal-rating": 0.5187773690879303, + "generated": 899, + "speedy": "solidungular", + "noviceship": "medicine", + "checkrow": "epidictic" + } + ] + } + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 62] + +RFC 8610 CDDL June 2019 + + +Acknowledgements + + Inspiration was taken from the C and Pascal languages, MPEG's + conventions for describing structures in the ISO base media file + format, RELAX NG and its compact syntax [RELAXNG], and, in + particular, Andrew Lee Newton's early proposals on JSON Content Rules + (JCR) as found in draft version four (-04) of [JCR]. + + Lots of highly useful feedback came from members of the IETF CBOR WG + -- in particular, Ari Keranen, Brian Carpenter, Burt Harris, Jeffrey + Yasskin, Jim Hague, Jim Schaad, Joe Hildebrand, Max Pritikin, Michael + Richardson, Pete Cordell, Sean Leonard, and Yaron Sheffer. Also, + Francesca Palombini and Joe volunteered to chair the WG when it was + created, providing the framework for generating and processing this + feedback, with Barry Leiba having taken over from Joe since then. + Chris Lonvick and Ines Robles provided additional reviews during IESG + processing, and Alexey Melnikov steered the process as the + responsible Area Director. + + The CDDL tool described in Appendix F was written by Carsten Bormann, + building on previous work by Troy Heninger and Tom Lord. + +Contributors + + CDDL was originally conceived by Bert Greevenbosch, who also wrote + the original five draft versions of this document. + + + + + + + + + + + + + + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 63] + +RFC 8610 CDDL June 2019 + + +Authors' Addresses + + Henk Birkholz + Fraunhofer SIT + Rheinstrasse 75 + Darmstadt 64295 + Germany + + Email: henk.birkholz@sit.fraunhofer.de + + + Christoph Vigano + Universitaet Bremen + + Email: christoph.vigano@uni-bremen.de + + + Carsten Bormann + Universitaet Bremen TZI + Bibliothekstr. 1 + Bremen D-28359 + Germany + + Phone: +49-421-218-63921 + Email: cabo@tzi.org + + + + + + + + + + + + + + + + + + + + + + + + + + +Birkholz, et al. Standards Track [Page 64] + |