Internet DRAFT - draft-luis140219-appsawg-zeroformat

draft-luis140219-appsawg-zeroformat



Internet Engineering Task Force (IETF)                         L. Camara
Internet-Draft                                             July 18, 2017
Intended Status: Standards Track
Expires: January 19, 2018


                          The .0 format (v1.2)
                 draft-luis140219-appsawg-zeroformat-01

   [[RFC-Editor: please replace the second character of my surname by
   U+00E2 when publishing as RFC in the header and in all pages.
   Non-ASCII characters are allowed in RFCs as per RFC 7997.]]

Abstract

  This document defines the .0 format, a format for transmitting data
  that can be efficiently parsed.

Status of This Memo

   This Internet-Draft is submitted in full conformance with the
   provisions of BCP 78 and BCP 79.

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF).  Note that other groups may also distribute
   working documents as Internet-Drafts.  The list of current Internet-
   Drafts is at http://datatracker.ietf.org/drafts/current/.

   Internet-Drafts are draft documents valid for a maximum of six months
   and may be updated, replaced, or obsoleted by other documents at any
   time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   This Internet-Draft will expire on January 19, 2018.

Copyright Notice

   Copyright (c) 2017 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
   (http://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  . . . . . . . . . . . . . . . . . . . . . . . . .  3
   2. Presentation Language . . . . . . . . . . . . . . . . . . . . .  3
   2.1. Syntax  . . . . . . . . . . . . . . . . . . . . . . . . . . .  3

Camara                  Expires January 19, 2018                [Page 1]

Internet-Draft                .0 format                        July 2017

   2.2. Semantics . . . . . . . . . . . . . . . . . . . . . . . . . .  4
   2.2.1. Typedef . . . . . . . . . . . . . . . . . . . . . . . . . .  5
   2.2.2. 8-bit integer . . . . . . . . . . . . . . . . . . . . . . .  5
   2.2.3. 16-bit integer  . . . . . . . . . . . . . . . . . . . . . .  6
   2.2.4. 32-bit integer  . . . . . . . . . . . . . . . . . . . . . .  6
   2.2.5. 64-bit integer  . . . . . . . . . . . . . . . . . . . . . .  7
   2.2.6. __m128  . . . . . . . . . . . . . . . . . . . . . . . . . .  7
   2.2.7. Float . . . . . . . . . . . . . . . . . . . . . . . . . . .  7
   2.2.8. Double  . . . . . . . . . . . . . . . . . . . . . . . . . .  8
   2.2.9. Long double . . . . . . . . . . . . . . . . . . . . . . . .  8
   2.2.10. Void . . . . . . . . . . . . . . . . . . . . . . . . . . .  8
   2.2.11. Structure  . . . . . . . . . . . . . . . . . . . . . . . .  9
   2.2.12. Union  . . . . . . . . . . . . . . . . . . . . . . . . . .  9
   2.2.13. Pointer  . . . . . . . . . . . . . . . . . . . . . . . . .  9
   2.3. Basic definitions . . . . . . . . . . . . . . . . . . . . . .  9
   2.4. Conventions . . . . . . . . . . . . . . . . . . . . . . . . . 10
   3. The format  . . . . . . . . . . . . . . . . . . . . . . . . . . 10
   3.1. The HashTable structure . . . . . . . . . . . . . . . . . . . 11
   3.2. The HashTableEntry structure  . . . . . . . . . . . . . . . . 12
   3.3. The UNICODE_STRING structure  . . . . . . . . . . . . . . . . 13
   3.4. The TypedData structure . . . . . . . . . . . . . . . . . . . 13
   3.4.1. Types with GUIDs  . . . . . . . . . . . . . . . . . . . . . 14
   3.4.2. Universal types . . . . . . . . . . . . . . . . . . . . . . 15
   3.4.2.1. The number type (0xFFFFFFFE)  . . . . . . . . . . . . . . 16
   3.4.2.2. The boolean type (0xFFFFFFFC) . . . . . . . . . . . . . . 16
   3.4.2.3. The string type (0xFFFFFFF6)  . . . . . . . . . . . . . . 16
   3.4.2.4. The X.690 data type (0xFFFFFFF5)  . . . . . . . . . . . . 16
   3.5. GUID  . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
   3.6. The Array structure . . . . . . . . . . . . . . . . . . . . . 17
   3.7. The ArrayEntry structure  . . . . . . . . . . . . . . . . . . 17
   3.8. Special properties of the root hash table . . . . . . . . . . 18
   3.8.1. ".::version"  . . . . . . . . . . . . . . . . . . . . . . . 18
   3.8.2. ".::purpose"  . . . . . . . . . . . . . . . . . . . . . . . 18
   3.8.3. ".::guid" . . . . . . . . . . . . . . . . . . . . . . . . . 18
   3.8.4. ".::signature"  . . . . . . . . . . . . . . . . . . . . . . 18
   3.8.5. ".::signature_pkcs7"  . . . . . . . . . . . . . . . . . . . 19
   3.8.6. ".::checksum" . . . . . . . . . . . . . . . . . . . . . . . 19
   4. IANA registries . . . . . . . . . . . . . . . . . . . . . . . . 21
   4.1. Type registry . . . . . . . . . . . . . . . . . . . . . . . . 21
   4.2. Owner name registry . . . . . . . . . . . . . . . . . . . . . 21
   5. Validation and Canonicalisation . . . . . . . . . . . . . . . . 21
   5.1. Algorithm A . . . . . . . . . . . . . . . . . . . . . . . . . 22
   5.1.1. Encoding a hash table . . . . . . . . . . . . . . . . . . . 22
   5.1.2. Encoding a hash table (to HashTableEntry) . . . . . . . . . 22
   5.1.3. Encoding a string . . . . . . . . . . . . . . . . . . . . . 23
   5.1.4. Encoding an array . . . . . . . . . . . . . . . . . . . . . 23
   5.1.5. Encoding an array (to ArrayEntry) . . . . . . . . . . . . . 23
   5.1.6. Encoding X.690 data . . . . . . . . . . . . . . . . . . . . 24
   5.1.7. Other types . . . . . . . . . . . . . . . . . . . . . . . . 24
   5.2. Algorithm B . . . . . . . . . . . . . . . . . . . . . . . . . 24
   6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . . 24

Camara                  Expires January 19, 2018                [Page 2]

Internet-Draft                .0 format                        July 2017

   7. Security Considerations . . . . . . . . . . . . . . . . . . . . 25
   8. References  . . . . . . . . . . . . . . . . . . . . . . . . . . 25
   8.1. Normative References  . . . . . . . . . . . . . . . . . . . . 25
   8.2. Informative References  . . . . . . . . . . . . . . . . . . . 26
   9. Author's Address  . . . . . . . . . . . . . . . . . . . . . . . 26
   Appendix A. Examples . . . . . . . . . . . . . . . . . . . . . . . 27
   Appendix A.1. Algorithm A result example . . . . . . . . . . . . . 27
   Appendix A.2. Algorithm B result example . . . . . . . . . . . . . 30
   Appendix A.3. About the examples . . . . . . . . . . . . . . . . . 33
   Appendix B. Writing related documents  . . . . . . . . . . . . . . 33
   Appendix C. Data leakage using a buffer underflow  . . . . . . . . 33

1. Introduction

   This document defines the .0 format, a format that can be parsed very
   efficiently and designed for real-world performance.

   This is version 1.2 of the specification. All features in this
   specification apply to all versions, i.e. v1.0+, unless otherwise
   stated.

   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.

2. Presentation Language

   The definitions in this document use the presentation language
   defined in this section.

2.1. Syntax

   This is the syntax of the presentation language, defined using the
   Augmented Backus-Naur Form (ABNF) [RFC5234, RFC7405], the core
   rules of Appendix B of [RFC5234] and the rule UTFMB defined in
   Section 1.4 of [RFC4512] (the encoding of the presentation language
   is UTF-8 [RFC3629]):

   deflist   =  1*( def / (*c-wsp c-nl) )

   c-wsp     =  WSP / (c-nl WSP)

   c-nl      =  comment / CRLF
                ; comment or newline

   comment   =  comment1 / comment2

   comment1  =  ( "//" / "#" ) *(WSP / VCHAR) CRLF
                ; single-line comments use // or #

Camara                  Expires January 19, 2018                [Page 3]

Internet-Draft                .0 format                        July 2017

   comment2  =  "/*" *( ( %x20-29 / %x2B-7E ) /
                  *( ( %x20-2E / %x30-7E / UTFMB ) ) ) "*/"
                ; multi-line comments use /* ... */

   def       =  typedef / struct1 / union1


   typedef   =  %s"typedef" *c-wsp type *c-wsp name
                (*c-wsp "," *c-wsp name) ";"

   name      =  ( ALPHA / "_" / "$" ) *( ALPHA / DIGIT / "_" / "$" )
                ; uses characters from [A-Za-z0-9_$] and first MUST NOT
                ; be a digit

   type      =  type0 *(c-wsp "*")
                ; pointers can be used in the presentation language

   type0     =  primitive / struct2 / union2 / name

   primitive =  ( u-len / [u-len] %s"int" ) /
                ( ["unsigned"] (%s"char" / %s"wchar_t" / ( %s"__int"
                  ( "8" | "16" | "32" | "64" ) ) ) ) / %s"__m128" /
                %s"float" / ( [%s"long"] %s"double" ) /
                %s"void"
                ; 1. int is always 32 bits.
                ; 2. Microsoft convention: wchar_t is 16 bits.
                ; 3. float is 32 bits, double is 64 bits, long double is
                ; 80 bits. See sections 2.2.7, 2.2.8 and 2.2.9 for more
                ; details.
                ; 4. __m128 is 128 bits.

   u-len     =  "unsigned" / ["unsigned"] length

   length    =  %s"short" / 1*2( %s"long" )
                ; short 16 bits, long 32 bits, long long 64 bits

   struct2   =  struct1 / ( %s"struct" *c-wsp struct *c-wsp ";" )

   struct1   =  %s"struct" *c-wsp name *c-wsp struct *c-wsp ";"

   struct    =  "{" *c-wsp *( type *c-wsp name
                ["[" number "]"]
                ";" / c-wsp ) "}"

   union2    =  union1 / ( %s"union" *c-wsp union *c-wsp ";" )

   union1    =  %s"union" *c-wsp name *c-wsp union *c-wsp ";"

   union     =  "{" *c-wsp *( type *c-wsp name ";" / c-wsp ) "}"

2.2. Semantics

Camara                  Expires January 19, 2018                [Page 4]

Internet-Draft                .0 format                        July 2017

2.2.1. Typedef

   typedef TYPE NEWTYPE;

   The type NEWTYPE is defined to be the same as TYPE and has the same
   size and structure.


2.2.2. 8-bit integer

   char
   unsigned char
   __int8
   unsigned __int8

    0 1 2 3 4 5 6 7
   +-+-+-+-+-+-+-+-+
   |    1 octet    |
   +-+-+-+-+-+-+-+-+

   The char type is normally signed, but can be unsigned in a C/C++
   compiler given certain options. "unsigned char" and "unsigned __int8"
   are always unsigned. "__int8" is always signed.

   The unsigned types here can represent values from 0 to 255, and the
   signed types here can represent values from -128 to 127. Two's
   complement is used for signed values:

    +---------------+----------+------------+-------+
    |0 1 2 3 4 5 6 7|Hex signed|Hex unsigned|Decimal|
    +---------------+----------+------------+-------+
    |1 0 0 0 0 0 0 0|   -0x80  |    0x80    |  -128 |
    |1 0 0 0 0 0 0 1|   -0x7F  |    0x81    |  -127 |
    |1 0 0 0 0 0 1 0|   -0x7E  |    0x82    |  -126 |
    .................................................
    .................................................
    |1 0 1 1 1 1 1 1|   -0x41  |    0xBF    |   -65 |
    |1 1 0 0 0 0 0 0|   -0x40  |    0xC0    |   -64 |
    |1 1 0 0 0 0 0 1|   -0x3F  |    0xC1    |   -63 |
    .................................................
    .................................................
    |1 1 1 1 1 1 1 0|   -0x02  |    0xFE    |    -2 |
    |1 1 1 1 1 1 1 1|   -0x01  |    0xFF    |    -1 |
    |0 0 0 0 0 0 0 0|   +0x00  |    0x00    |    +0 |
    |0 0 0 0 0 0 0 1|   +0x01  |    0x01    |    +1 |
    |0 0 0 0 0 0 1 0|   +0x02  |    0x02    |    +2 |
    .................................................
    .................................................
    |0 1 1 1 1 1 1 0|   +0x7E  |    0x7E    |  +126 |
    |0 1 1 1 1 1 1 1|   +0x7F  |    0x7F    |  +127 |
    +---------------+----------+------------+-------+

Camara                  Expires January 19, 2018                [Page 5]

Internet-Draft                .0 format                        July 2017

2.2.3. 16-bit integer

   short
   unsigned short
   short int
   unsigned short int
   __int16
   unsigned __int16
   wchar_t

                        1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_0      |      o_1      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   (size = 2 octets = 16 bits)

   The octet order is little-endian: this means the value is
   256*o_1 + o_0, with o_1 being signed if and only if the type is
   signed.

   From the first 6 types, the ones with "unsigned" are unsigned, the
   others are signed. wchar_t is unsigned.

2.2.4. 32-bit integer

   int
   unsigned int
   long
   unsigned long
   long int
   unsigned long int
   __int32
   unsigned __int32

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_0      |      o_1      |      o_2      |      o_3      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   (size = 4 octets = 32 bits)

   The octet order is little-endian: this means the value is
   16777216*o_3 + 65536*o_2 + 256*o_1 + o_0, with o_3 being signed if
   and only if the type is signed.

   From these 8 types, the ones with "unsigned" are unsigned, the others
   are signed.


Camara                  Expires January 19, 2018                [Page 6]

Internet-Draft                .0 format                        July 2017

2.2.5. 64-bit integer

   long long
   unsigned long long
   long long int
   unsigned long long int
   __int64
   unsigned __int64

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_0      |      o_1      |      o_2      |      o_3      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_4      |      o_5      |      o_6      |      o_7      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   (size = 8 octets = 64 bits)

   The octet order is little-endian: this means the value is
   (2^^56)*o_7 + (2^^48)*o_6 + (2^^40)*o_5 + (2^^32)*o_4 +
   16777216*o_3 + 65536*o_2 + 256*o_1 + o_0, with o_7 being signed if
   and only if the type is signed.

   From these 6 types, the ones with "unsigned" are unsigned, the others
   are signed.

2.2.6. 128-bit data

   __m128

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_0      |      o_1      |      o_2      |      o_3      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_4      |      o_5      |      o_6      |      o_7      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_8      |      o_9      |      o_10     |      o_11     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_12     |      o_13     |      o_14     |      o_15     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   (size = 16 octets = 128 bits)

   This type is the in-memory representation of a XMM register in an
   Intel x86/x64 CPU supporting MMX and, therefore, is 128 bits in size.

2.2.7. Float

   float

Camara                  Expires January 19, 2018                [Page 7]

Internet-Draft                .0 format                        July 2017

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_0      |      o_1      |      o_2      |      o_3      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   (size = 4 octets = 32 bits)

   This type is the in-memory representation of a 32-bit floating-point
   value in an Intel x87 FPU or in an Intel 80486+/x64 CPU.

2.2.8. Double

   double

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_0      |      o_1      |      o_2      |      o_3      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_4      |      o_5      |      o_6      |      o_7      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   (size = 8 octets = 64 bits)

   This type is the in-memory representation of a 64-bit floating-point
   value in an Intel x87 FPU or in an Intel 80486+/x64 CPU.

2.2.9. Long double

   long double

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_0      |      o_1      |      o_2      |      o_3      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_4      |      o_5      |      o_6      |      o_7      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_8      |      o_9      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   (size = 10 octets = 80 bits)

   This type is the in-memory representation of an 80-bit floating-point
   value in an Intel x87 FPU or in an Intel 80486+/x64 CPU.

2.2.10. Void

   void


Camara                  Expires January 19, 2018                [Page 8]

Internet-Draft                .0 format                        July 2017

   (size = 0 bytes)

   This type is 0 bytes in size and is useful to indicate the absence of
   a return value or arguments in a C/C++ function. A void* pointer

2.2.11. Structure

   struct { ... }
   struct NAME { ... };

   The structure type has a size equal to the sum of the size of all its
   components and has the structure of the concatenation of its
   components.

2.2.12. Union

   union { ... };
   union NAME { ... };

   The union type has a size equal to the maximum of the size of its
   components and every component's value is at the start of the union.

2.2.13. Pointer

   TYPE*

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_0      |      o_1      |      o_2      |      o_3      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   This has the same size and value semantics as a 32-bit integer
   (Section 2.2.4), but can be dereferenced by returning the value of
   type TYPE at N octets from the pointer base, where N is the integer
   value of the pointer.

   Adding to a pointer of type TYPE* returns N+V*S, where N is the
   integer value of the pointer, V is the integer value added to the
   pointer and S is the size of the type TYPE in octets.

2.3. Basic definitions

   This is a set of basic definitions used throughout this document,
   defined in the presentation language defined above.

   /// <summary>
   /// Represents an 8-bit integer.
   /// </summary>
   typedef __int8 int8_t;
   /// <summary>

Camara                  Expires January 19, 2018                [Page 9]

Internet-Draft                .0 format                        July 2017

   /// Represents an unsigned 8-bit integer.
   /// </summary>
   typedef unsigned __int8 uint8_t;
   /// <summary>
   /// Represents a 16-bit integer.
   /// </summary>
   typedef short int16_t;
   /// <summary>
   /// Represents an unsigned 16-bit integer.
   /// </summary>
   typedef unsigned short uint16_t;
   /// <summary>
   /// Represents a 32-bit integer.
   /// </summary>
   typedef long int32_t;
   /// <summary>
   /// Represents an unsigned 32-bit integer.
   /// </summary>
   typedef unsigned long uint32_t;
   /// <summary>
   /// Represents a 64-bit integer.
   /// </summary>
   typedef __int64 int64_t;
   /// <summary>
   /// Represents an unsigned 64-bit integer.
   /// </summary>
   typedef unsigned __int64 uint64_t;

2.4. Conventions

   The definitions use XML comments for being able to self-document in
   Microsoft Visual Studio, and the language is totally compatible with
   C/C++, assuming wchar_t is 2 octets (16 bits), int is 4 octets (32
   bits), that __int8, __int16, __int32 and __int64 are working
   keywords, that a pointer is 4 octets (32 bits), that nameless unions
   are supported and that the endianness is little-endian (everything
   here is true for Microsoft's C/C++ Compiler targeting a WOW64/x86
   architecture).

   For the .0 format specification, the "pointer base" in Section 2.2.13
   refers to the start of the data using the format.

3. The format

   The format has the following header:

   /// <summary>
   /// Represents the .0 format header (16 bytes).
   /// </summary>
   struct ZeroHeader {
     /// <summary>

Camara                  Expires January 19, 2018               [Page 10]

Internet-Draft                .0 format                        July 2017

     /// Magic. MUST be "lm_data\0".
     /// </summary>
     uint8_t Magic[8];
     /// <summary>
     /// Data mode. 0 - not canonicalised, 1 - algorithm A, 2 -
     /// algorithm B.
     /// </summary>
     uint32_t Mode;
     /// <summary>
     /// Reserved, MUST be set to 0 and SHOULD be ignored.
     /// </summary>
     uint32_t Reserved;
     /// <summary>
     /// The root hash table of this data.
     /// </summary>
     HashTable Root;
   };

   This header is 20 octets in size.

   The Magic field is the magic number for the .0 format and MUST be set
   to 6C 6D 5F 64 61 74 61 00 (ASCII [RFC20] "lm_data" followed by NUL).

   The Mode field MUST be set to 0 if the data was not canonicalised,
   MUST be set to 1 if the data was canonicalised with algorithm A of
   Section 5 and MUST be set to 2 if the data was canonicalised with
   algorithm A of Section 5. Other values SHALL be
   The Reserved field is reserved, MUST be set to 0 by generators of
   data using this format and SHOULD be ignored by data parsers and
   readers (Section YY).

   The Size field of the HashTable (Section 3.1) Root MUST NOT be
   negative and MUST be the size of the entire data (including the
   header) (this "MUST" conflicts with Section 3.1, and this section
   takes priority). For stored files, it is RECOMMENDED that Size be a
   multiple of 4096.

   Following the header comes a HashTableEntry structure
   (Section 3.2).

3.1. The HashTable structure

   The HashTable structure is defined as follows:

   /// <summary>
   /// Represents a hash table in the .0 format.
   /// </summary>
   struct HashTable {
     /// <summary>
     /// Size of the hash table, in bytes.
     /// </summary>

Camara                  Expires January 19, 2018               [Page 11]

Internet-Draft                .0 format                        July 2017

     int Size;
     /// <summary>
     /// Count of name-value pairs in the hash table.
     /// </summary>
     int Count;
   };

   (size = 8 octets)

   The Size field MUST be set to the number of contiguous octets
   following the Size field that are part of the hash table represented
   by the structure. The Count field MUST be the count of name-value
   pairs in the hash table represented by the structure.

   If the Size field is not 0, a HashTableEntry structure (Section 3.2)
   MUST follow the Size field.

3.2. The HashTableEntry structure

   /// <summary>
   /// Represents a hash table entry in the .0 format.
   /// </summary>
   struct HashTableEntry {
     /// <summary>
     /// Next entry. NULL if there is no next entry.
     /// </summary>
     HashTableEntry* Next;
     /// <summary>
     /// Name part of the hash table entry, in Unicode.
     /// </summary>
     UNICODE_STRING Name;
     /// <summary>
     /// Value part of the hash table entry.
     /// </summary>
     TypedData Data;
   };

   (size = 24 octets)

   The Next pointer points to the next entry in the hash table. This
   pointer is 0 when there is no next entry.

   The Name pointer describes the name associated with the value
   described by Data.
   See Section 3.3 for the UNICODE_STRING structure.

   The Data pointer specifies the type, length and pointer to the value
   associated with the name. The TypedData structure is specified in
   Section 3.4.



Camara                  Expires January 19, 2018               [Page 12]

Internet-Draft                .0 format                        July 2017

3.3. The UNICODE_STRING structure

   /// <summary>
   /// Represents a Unicode string.
   /// </summary>
   struct UNICODE_STRING {
     /// <summary>
     /// Length, in bytes, of the string of Unicode characters.
     /// </summary>
     uint16_t Length;
     /// <summary>
     /// Size of the buffer, in bytes.
     /// </summary>
     uint16_t BufferLength;
     /// <summary>
     /// Buffer containing the Unicode characters (UTF-16LE).
     wchar_t* Buffer;
   };

   (size = 8 octets)

   <https://msdn.microsoft.com/en-us/library/windows/hardware/
   ff564879(v=vs.85).aspx>

   The Length is the length, in octets, of the string of wide characters
   pointed to by the Buffer member.

   The BufferLength is the length, in octets, of the buffer pointed to
   by the Buffer member.

   The Buffer member points to a string of 2-byte Unicode characters
   using UTF-16LE [RFC2781].

3.4. The TypedData structure

   /// <summary>
   /// Represents typed data in the .0 format.
   /// </summary>
   struct TypedData {
     /// <summary>
     /// Pointer to the value.
     /// </summary>
     void* Value;
     /// <summary>
     /// Type of the value.
     /// </summary>
     int Type;
     /// <summary>
     /// Length of the value, in bytes.
     /// </summary>
     int Size;

Camara                  Expires January 19, 2018               [Page 13]

Internet-Draft                .0 format                        July 2017

   };

   The Value field MUST point to valid data of size Size octets.

   The Size field MUST NOT be negative, but MAY be 0.

   The Type field is the type of the data pointed to by Value.

   +----------------+--------------------------------------------------+
   |Most significant|                                                  |
   |4 bits of Type  |                    Meaning                       |
   +----------------+--------------------------------------------------+
   |  0   x   x   x | Free for use                                     |
   |  1   0   y   z | Type identified by GUID (see Section 3.4.1)      |
   |  1   1   0   x | Reserved (Section 4.1)                           |
   |  1   1   1   0 | Reserved (Section 4.1)                           |
   |  1   1   1   1 | Universal types                                  |
   +----------------+--------------------------------------------------+

   x - don't care bit, y and z - used in Section 3.4.1.

3.4.1. Types with GUIDs

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  h_0  |  l_0  |  h_1  |  l_1  |  h_2  |  l_2  |1|0|y|z|  l_3  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   A Type member with the above structure uses the GUID (Section 3.5)
   pointed to by a GUID* with the following structure:

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  l_0  |y|z|0|0|  l_1  |  h_0  |  l_2  |  h_1  |  l_3  |  h_2  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   This can be done very efficiently in a x86 CPU with the following
   function defined in NASM assembly using __fastcall:

   ; GUID* __fastcall TypeToGUID(int Type)
   ; Assumes Type has the two MSBs 1 and 0.
   TypeToGUID:         ; Example: convert     0xA1234567 to GUID*
   mov eax, ecx        ; eax=0xA1234567,  ecx=0xA1234567
   shr ecx, 26         ; eax=0xA1234567,  ecx=0x00000028
   and ecx, byte +0x0C ; eax=0xA1234567,  ecx=0x00000008
   shl eax, 4          ; eax=0x12345670,  ecx=0x00000008
   or eax, ecx         ; eax=0x12345678,  ecx=0x12345678
   ret                 ; Result=0x12345678


Camara                  Expires January 19, 2018               [Page 14]

Internet-Draft                .0 format                        July 2017

   Portable and endian-neutral C implementation (a C version of the
   above assembly code):

   /// <summary>
   /// Converts a .0 type to a GUID pointer in the presentation language
   /// of the .0 specification (Section 2.2.13).
   /// </summary>
   /// <param name="Type">The type value to convert.</param>
   /// <returns>The obtained GUID pointer.</returns>
   GUID* TypeToGUID(int Type) {
     return (GUID*)(((Type >> 26) & 0x0C) + (Type << 4));
   }

3.4.2. Universal types

   The following universal types are defined:

   +----------+-------------+---------------+--------------------------+
   |Type value|Type         |Minimum version|Section/remarks           |
   +----------+-------------+---------------+--------------------------+
   |0xFFFFFFFF|String       |v1.0           |Section 3.3               |
   +----------+-------------+---------------+--------------------------+
   |0xFFFFFFFE|Number       |v1.0           |Section 3.4.2.1           |
   +----------+-------------+---------------+--------------------------+
   |0xFFFFFFFD|Program      |To be defined  |This type is not defined  |
   +----------+-------------+---------------+--------------------------+
   |0xFFFFFFFC|Boolean      |v1.0           |Section 3.4.2.2           |
   +----------+-------------+---------------+--------------------------+
   |0xFFFFFFFB|Float        |v1.0           |Section 2.2.7             |
   +----------+-------------+---------------+--------------------------+
   |0xFFFFFFFA|Double       |v1.0           |Section 2.2.8             |
   +----------+-------------+---------------+--------------------------+
   |0xFFFFFFF9|Long double  |v1.0           |Section 2.2.9             |
   |          |(TWORD)      |               |                          |
   +----------+-------------+---------------+--------------------------+
   |0xFFFFFFF8|Array        |v1.0           |Section 3.6               |
   +----------+-------------+---------------+--------------------------+
   |0xFFFFFFF7|Object       |v1.0           |Section 3.1               |
   +----------+-------------+---------------+--------------------------+
   |0xFFFFFFF6|Binary       |v1.0           |Section 3.4.2.3           |
   +----------+-------------+---------------+--------------------------+
   |0xFFFFFFF5|X.690 data   |v1.1           |Section 3.4.2.5           |
   +----------+-------------+---------------+--------------------------+
   |0xFFFFFFF4|GUID         |v1.1           |Section 3.5               |
   +----------+-------------+---------------+--------------------------+

   (In version 1.1, 0xFFFFFFF5 was "embedded ASN.1". The new name was
   adopted in version 1.2.)

   Universal types are allocated via the IANA registry defined in
   Section 4.1.

Camara                  Expires January 19, 2018               [Page 15]

Internet-Draft                .0 format                        July 2017

3.4.2.1. The number type (0xFFFFFFFE)

   The number type represents a signed arbitrary-precision integer. A
   signed integer of a fixed size can be transformed into this format by
   initialising the value's octets with the signed integer's octets (in
   little-endian) and setting the Size field to the size of the signed
   integer, in octets.

3.4.2.2. The boolean type (0xFFFFFFFC)

   The boolean type MUST have its associated Size field equal to 1 or 4,
   and it is true if and only if at least one of the octets of its value
   is not 0x00.

3.4.2.3. The binary type (0xFFFFFFF6)

   The binary type represents an octet string, whose value octets are
   those of the octet string.

3.4.2.4. The X.690 data type (0xFFFFFFF5)

   The X.690 data type MUST contain a valid Basic Encoding Rules
   (BER) [X.690] structure in its value octets.

3.5. GUID

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_3      |      o_2      |      o_1      |      o_0      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_5      |      o_4      |      o_7      |      o_6      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_8      |      o_9      |      o_10     |      o_11     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      o_12     |      o_13     |      o_14     |      o_15     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   (size = 16 octets = 128 bits)

   The value is structured as above and the octets from o_0 to o_15
   (in this order) represent an UUID as in [RFC4122]. GUID is a term
   used in Windows programming, that represents an UUID with native
   endianness (for the .0 format, little-endian) for some fields.

   The Microsoft version of the definition is available at
   <https://msdn.microsoft.com/en-us/library/windows/desktop/
   aa373931(v=vs.85).aspx>.




Camara                  Expires January 19, 2018               [Page 16]

Internet-Draft                .0 format                        July 2017

3.6. The Array structure

   The Array structure is defined as follows:

   /// <summary>
   /// Represents an array in the .0 format.
   /// </summary>
   struct Array {
     /// <summary>
     /// Size of the array, in bytes.
     /// </summary>
     int Size;
     /// <summary>
     /// Count of elements in the array.
     /// </summary>
     int Count;
   };

   (size = 4 octets)

   The Size field MUST be set to the number of contiguous octets
   following the Size field that are part of the array represented by
   the structure. The Count field MUST be the count of elements in the
   array represented by the structure.

   If the Size field is not 0, an ArrayEntry structure (Section 3.7)
   MUST follow the Size field.

3.7. The ArrayEntry structure

   /// <summary>
   /// Represents an array entry in the .0 format.
   /// </summary>
   struct ArrayEntry {
     /// <summary>
     /// Next entry. NULL if there is no next entry.
     /// </summary>
     ArrayEntry* Next;
     /// <summary>
     /// Value of this entry.
     /// </summary>
     TypedData Data;
   };

   (size = 16 octets)

   The Next pointer points to the next entry in the array. This pointer
   is 0 when there is no next entry.




Camara                  Expires January 19, 2018               [Page 17]

Internet-Draft                .0 format                        July 2017

   The Data pointer specifies the type, length and pointer to the value
   of this entry of the array. The TypedData structure is specified in
   Section 3.4.

3.8. Special properties of the root hash table

   The initial hash table entry in data using the .0 format is the first
   hash table entry in the root hash table. Here are defined some
   properties of the root hash table with names starting with ".::".

3.8.1. ".::version"

   It is RECOMMENDED that a value associated with the name ".::version"
   exist. If present, the value MUST have type String (0xFFFFFFFF, see
   sections 3.4.2 and 3.3) and MUST contain the version of the format
   used for the data (e.g. "v1.0" or "v1.2"). Encoders for version A
   of the .0 format SHOULD set the ".::version" field to A.

   If a decoder for version A of the .0 format receives data encoded in
   an earlier version B of the .0 format and it contains features
   specific to versions later than B, the decoder MAY raise a warning.

   If present, the ".::version" MUST be the first name in the root hash
   table.

3.8.2. ".::purpose"

   This value, if present, MUST have type String (0xFFFFFFFF, see
   sections 3.4.2 and 3.3) and MUST contain an owner name, followed by
   two colons "::" and by a local identifier. It is RECOMMENDED that
   local identifiers match the following regular expression
   (JavaScript):

   The company owning an owner name can freely use the names starting
   with any of its owner names followed by "::".

   The name "IETF" is an owner name of the Internet Engineering Task
   Force (IETF) and "." is an owner name of the authorities managing
   this format. Owner names are assigned by IANA in the registry defined
   in Section 4.2.

3.8.3. ".::guid"

   This value, if present, MUST have type Binary (0xFFFFFFF6, see
   Section 3.4.2.3), MUST be 16 octets in size and MUST contain a GUID
   structure (Section 3.5) identifying the data. Procedures for these
   identifiers are detailed in Section 3.5 and [RFC4122].

3.8.4. ".::signature"

   This value, if present, MUST have type X.690 data (0xFFFFFFF5, see

Camara                  Expires January 19, 2018               [Page 18]

Internet-Draft                .0 format                        July 2017

   Section 3.4.2.4), is available since v1.1 and uses the following
   ASN.1 structure [X.680]:

   ZeroSig ::= SEQUENCE {
     algorithm OBJECT IDENTIFIER,
     [0] signingCertificate EXPLICIT X509Cert OPTIONAL,
     [1] intermediateCertificates IMPLICIT Intermediates OPTIONAL,
     rootCertificate X509Cert,
     [2] test IMPLICIT BOOLEAN OPTIONAL,
     hash BIT STRING
   }

   (X509Cert is the Certificate type from Appendix A.1 of [RFC5280])

   This value SHOULD NOT be used in version 1.2 and later of the .0
   format as it is deprecated in favour of ".::signature_pkcs7"
   (Section 3.8.5).

3.8.5. ".::signature_pkcs7"

   This value, if present, MUST have type X.690 data (0xFFFFFFF5, see
   Section 3.4.2.4), is available since v1.2 and MUST contain a valid
   PKCS#7 structure [RFC5652] with contentType signedData
   (1.2.840.113549.1.7.2), whose eContentType MUST be
   1.3.6.1.4.1.37476.9000.46.2.7.2 (id-zeroDigest), that contains a
   ZeroDigest described in ASN.1 [X.680] below:

   ZeroDigest ::= SEQUENCE {

   }

   The ZeroDigest, to the digital signature in the data to be valid,
   MUST have the hash in the OCTET STRING equal to the hash using the
   algorithm identified by the AlgorithmIdentifier on the entire .0
   data, excluding the octets of the values associated with the names
   ".::checksum" (if present) and ".::signature_pkcs7", if present.

3.8.6. ".::checksum"

   This value, if present, MUST have type binary (0xFFFFFFF6, see
   Section 3.4.2.3), is available since v1.1, MUST be 400 octets in size
   and MUST contain a structure as follows (defined in the presentation
   language of Section 2):

   /// <summary>
   /// Represents the checksum in .0 data.
   /// </summary>
   struct ZeroChecksum {
     /// <summary>
     /// The GUID of the format. MUST be
     /// BC72DD96-194F-11E7-82B1-E4F89C5A2296 using the GUID structure

Camara                  Expires January 19, 2018               [Page 19]

Internet-Draft                .0 format                        July 2017

     /// (Section 3.5 of the .0 specification).
     /// </summary>
     GUID guid1;
     /// <summary>
     /// The SHA3-512 hash of the entire .0 data, excluding the octets
     /// composing this structure.
     /// </summary>
     char sha3_512[64];
     /// <summary>
     /// The Skein-512-512 hash of the entire .0 data, excluding the
     /// octets composing this structure.
     /// </summary>
     char skein[64];
     /// <summary>
     /// The CubeHash160+16/32+160-512 hash of the entire .0 data,
     /// excluding the octets composing this structure.
     /// </summary>
     char cubehash[64];
     /// <summary>
     /// The SHA-512 hash of the entire .0 data, excluding the octets
     /// composing this structure.
     /// </summary>
     char sha512[64];
     /// <summary>
     /// The SHA-384 hash of the entire .0 data, excluding the octets
     /// composing this structure.
     /// </summary>
     char sha384[48];
     /// <summary>
     /// The SHA-256 hash of the entire .0 data, excluding the octets
     /// composing this structure.
     /// </summary>
     char sha256[32];
     /// <summary>
     /// The SHA-224 hash of the entire .0 data, excluding the octets
     /// composing this structure.
     /// </summary>
     char sha224[28];
     /// <summary>
     /// The SHA-1 hash of the entire .0 data, excluding the octets
     /// composing this structure.
     /// </summary>
     char sha1[20];
   };

   (size = 400 octets)

   The checksum is valid if and only if the hashes contained in the
   checksum structure match the hashes obtained by hashing the entire .0
   data, excluding the octets composing the checksum structure.


Camara                  Expires January 19, 2018               [Page 20]

Internet-Draft                .0 format                        July 2017

   SHA-1 is defined in [SHA1], SHA-* is defined in [SHA2], SHA3-512
   is defined in [SHA3], Skein-512-512 is defined in [SKEIN] and
   CubeHash160+16/32+160-512 is defined in [CUBE].

4. IANA registries

   This document requires that IANA create the registries defined below.

4.1. Type registry

   This registry is named ".0 type registry".

   Values 0x00000000 to 0x7FFFFFFF are Private Use [RFC8126].
   Values 0x80000000 to 0xBFFFFFFF are Standards Action [RFC8126], with
   a reference to Section 3.4.1 of this document.
   Values 0xC0000000 to 0xEFFFFFFF are Specification Required [RFC8126].
   Values 0xF0000000 to 0xFFFFFFFF are Standards Action [RFC8126].
   Values 0xFFFFFFF4 to 0xFFFFFFFF include a reference to Section 3.4.2
   of this document.

   Universal types SHOULD be allocated in reverse order (example:
   0xFFFFFFF3 is allocated, then 0xFFFFFFF2, then 0xFFFFFFF1, etc...).

4.2. Owner name registry

   This registry is named ".0 owner name registry".

   The registered values are strings that MUST NOT contain the character
   ":".

   Owner names that are registered trademarks SHOULD NOT be owner names
   of companies that do not own the registered trademark.

5. Validation and Canonicalisation

   Data using the .0 format is valid if and only if all the following
   conditions apply:
   * it complies with all rules of Section 2 and Section 3;
   * one of the following applies:
     $ the Mode field is 0;
     $ the Mode field is unrecognised by the implementation;
     $ all of the following apply:
       * the Mode field is recognised by the implementation;
       * the data is valid in the canonicalisation form described by the
         Mode field.







Camara                  Expires January 19, 2018               [Page 21]

Internet-Draft                .0 format                        July 2017

   For any canonicalisation form, its recognition is OPTIONAL. The above
   validation algorithm implies that it is REQUIRED that a
   canonicalisation form be employed if it is recognised (this means to
   consider invalid data that claims to comply to a canonicalisation
   form and doesn't comply, see the security considerations in
   Section 7).

   In the following algorithms, the "header" is the target data
   structure of each encoding algorithm. The ".0 header" is the header
   of the data itself.

5.1. Algorithm A

   Algorithm A is as follows:

   1. Set Magic to "lm_data\0" (the magic number).
   2. Set Mode to 1 and Reserved to 0.
   3. Apply the algorithm of Section 5.1.2 to the hash table to be
        encoded with pos = 24, resulting in two values: n and S.
   4. Set Size to (n + 4119) & -4096. (This will align the data to
        4096 bytes).
   5. Append S to the header, resulting in T.
   6. Pad T to Size octets using octets with value 0x00.
   7. The canonicalised data is T.

5.1.1. Encoding a hash table

   1. Set Count to the number of name-value pairs in the hash table.
   2. If the hash table is empty, set Size to 0 and the results are 8
        and the hash table header.
   3. Encode the hash table using the algorithm of section 5.1.2,
        being the pos used for the encoding algorithm equal to pos + 4,
        resulting in n and S.
   4. Append S to the header, resulting in T.
   5. The results are (n + 8) and T.

5.1.2. Encoding a hash table (to HashTableEntry)

   1. Let s and v be the name and value of the first pair of the hash
        table (s is encoded in UTF-16LE [RFC2781]).
   2. Let l be the length of s, in octets.
   3. Set Name.Length to l.
   4. Let b be (l + 5) & -4.
   5. Set Name.BufferLength to b.
   6. Set Name.Buffer to pos + 24.
   7. Set Data.Value to (void*)(pos + 24 + b).
   8. Encode v using the algorithm in this section according to its
        type, being the pos used for the encoding algorithm equal to
        pos + 24 + b, resulting in two values, n and S.
   9. Set Data.Type to the type of the value (Section 3.4).
   10. Set Data.Length to n.

Camara                  Expires January 19, 2018               [Page 22]

Internet-Draft                .0 format                        July 2017

   11. Append s and S to the header, resulting in T.
   12. Pad T to the next multiple of 4 octets using octets with value
        0x00.
   13. Let t = (27 + b + n) & -4.
   14. If there is only one name-value pair in the hash table, set Next
        to (HashTableEntry*)(0), the results are t and T and this
        algorithm terminates.
   15. Encode the remaining name-value pairs of the hash table according
        to this algorithm, being the pos used equal to pos + t,
        resulting in u and U.
   16. Set Next in T to (void*)(pos + t).
   17. Append U to T, resulting in V.
   18. The results are (t + u) and V.

5.1.3. Encoding a string

   1. Let s be the UTF-16LE [RFC2781] encoding of the string.
   2. Let l be the length of s, in octets.
   3. Set Length to l.
   4. Let b be (l + 5) & -4.
   5. Set BufferLength to b.
   6. Set Buffer to pos + 8.
   7. Append s to the header, resulting in S.
   8. The results are (8 + b) and S.

5.1.4. Encoding an array

   1. If the array is empty, set Size to 0 and the results are 8 and the
       array header.
   2. Encode the array using the algorithm of section 5.1.5, being the
       pos used for the encoding algorithm equal to pos + 8, resulting
       in n and S.
   3. Append S to the header, resulting in T.
   4. The results are (n + 8) and T.

5.1.5. Encoding an array (to ArrayEntry)

   1. Let v be the first value of the array.
   2. Encode v using the algorithm in this section according to its
        type, being the pos used for the encoding algorithm equal to
        pos + 16, resulting in two values, n and S.
   3. Set Data.Type to the type of the value (Section 3.4).
   4. Set Data.Length to n.
   5. Append s and S to the header, resulting in T.
   6. Pad T to the next multiple of 4 octets using octets with value
       0x00.
   7. Let t = (19 + n) & -4.
   8. If there is is only one element in the array, set Next to
       (ArrayEntry*)(0), the results are t and T and this algorithm
       terminates.
   9. Encode the array, except for the first element, according to this

Camara                  Expires January 19, 2018               [Page 23]

Internet-Draft                .0 format                        July 2017

       to this algorithm, being the pos used equal to pos + t, resulting
       in u and U.
   10. Set Next in T to (void*)(pos + t).
   11. Append U to T, resulting in V.
   12. The results are (t + u) and V.

5.1.6. Encoding X.690 data

   X.690 data canonicalised using Algorithm A MUST use the Distinguished
   Encoding Rules (DER) of [X.690].

5.1.7. Other types

   Algorithms A and B do not pose constraints on other types as of
   version 1.2. Only types introduced in later versions may get subject
   to constraints by canonicalisation.

5.2. Algorithm B

   Algorithm B is very similar to Algorithm A, except that strings are
   stored in a temporary hash table, that begins empty, to save space
   and the result is not aligned to 4096 bytes. Formally, these are the
   changes to Algorithm A resulting in Algorithm B:
   Section 5.1, step 4 is replaced with "Set Size to n + 24."
   Section 5.1, step 6 is omitted.


   Section 5.1.2, step 7 is replaced with "If s is in the string hash
       table, set b to 0, set s to an empty sequence of octets and set
       Name.Buffer to the associated value in the string hash table.
       Otherwise, associate this value with s. After these substeps, set
       Data.Value to (void*)(pos + 24 + b).
   Section 5.1.3, step 7 is replaced with "If s is in the string hash
       table, set b to 0, set s to an empty sequence of octets, set
       Buffer to the associated value in the string hash table and let S
       be the header. Otherwise, append s to the header, resulting in
       S.".

   "b" becomes a mutable variable in the algorithms of Section 5.1.2 and
     Section 5.1.3.

6. IANA Considerations

   A MIME type may need to be registered for this format. The file
   extension is .0 and the magic number is 6C 6D 5F 64 61 74 61 00.

   The registries defined in Section 4 MUST be created by IANA.





Camara                  Expires January 19, 2018               [Page 24]

Internet-Draft                .0 format                        July 2017

7. Security Considerations

   Implementations SHALL validate data using the .0 format to assure
   there is no data leakage or denial of service attacks. (For an attack
   that targets implementations violating the "no data leakage"
   requirement, see Appendix C.) If a certain data using the .0 format
   is invalid, the data MUST be rejected and the system handling the
   data MUST either give out no response or give a response indicating
   to the peer the data is invalid.

   A protocol using this format MAY impose further restrictions on the
   files, for example, enforcing digital signatures, checksums and/or
   canonicalisation and rejecting unsigned or uncanonicalised files.

8. References

8.1. Normative References

   [CUBE]    Bernstein, D., "CubeHash specification (2.B.1)",
             <https://cubehash.cr.yp.to/submission2/spec.pdf>

   [RFC20]   Cerf, V., "ASCII format for network interchange", STD 80,
             RFC 20, October 1969.

   [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
             Requirement Levels", BCP 14, RFC 2119, March 1997.

   [RFC2781] Hoffman, P., and F. Yergeau, "UTF-16, an encoding of ISO
             10646", RFC 2781, February 2000.

   [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646",
             STD 63, RFC 3629, November 2003.

   [RFC4122] Leach, P., Mealling, M., and R. Salz, "A Universally Unique
             IDentifier (UUID) URN Namespace", RFC 4122, July 2005.

   [RFC4512] Zeilenga, K., "Lightweight Directory Access Protocol
             (LDAP): Directory Information Models", RFC 4512, June 2006.

   [RFC5234] Crocker, D., and P. Overell, "Augmented BNF for Syntax
             Specifications: ABNF", STD 68, RFC 5234, January 2008.

   [RFC5652] Housley, R., "Cryptographic Message Syntax (CMS)",
             STD 70, RFC 5652, September 2009.

   [RFC7405] Kyzivat, P., "Case-Sensitive String Support in ABNF",
             RFC 7405, December 2014.

   [RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for
             Writing an IANA Considerations Section in RFCs", BCP 26,
             RFC 8126, June 2017.

Camara                  Expires January 19, 2018               [Page 25]

Internet-Draft                .0 format                        July 2017

   [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119
             Key Words", BCP 14, RFC 8174, May 2017.

   [SHA1]    "Secure Hash Standard", United States of America, National
             Institute of Science and Technology, Federal Information
             Processing Standard (FIPS) 180-1, April 1993.

   [SHA2]    "Secure Hash Standard", United States of America, National
             Institute of Standards and Technology, Federal Information
             Processing Standard (FIPS) PUB 180-4, March 2012.

   [SHA3]    Drowkin, M., "SHA-3 Standard: Permutation-Based Hash and
             Extendable-Output Functions", United States of America,
             National Institute of Standards and Technology, Federal
             Information Processing Standard (FIPS) PUB 202, DOI
             10.6028/NIST.FIPS.202, <https://dx.doi.org/10.6028/
             NIST.FIPS.202> (currently redirects to <http://
             nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf>).

   [SKEIN]   Ferguson, N., Lucks, S., Schneier, B., et al., "The Skein
             Hash Function Family", Version 1.3, 1 October 2010,
             <http://www.skein-hash.info/sites/default/files/
             skein1.3.pdf>.

   [X.680]   ITU-T Recommendation X.680 (2002) | ISO/IEC 8824-1:2002,
             Information technology - Abstract Syntax Notation One
             (ASN.1): Specification of basic notation.

   [X.690]   ITU-T Recommendation X.690 (2002) | ISO/IEC 8825-1:2002,
             Information technology - ASN.1 encoding rules:
             Specification of Basic Encoding Rules (BER), Canonical
             Encoding Rules (CER) and Distinguished Encoding Rules
             (DER).

8.2. Informative References

   [RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S.,
             Housley, R., and W. Polk, "Internet X.509 Public Key
             Infrastructure Certificate and Certificate Revocation List
             (CRL) Profile", RFC 5280, May 2008.

   [[RFC-Editor: please replace the 'i' in my name by U+00ED and the
   first 'a' in the surname by U+00E2, as non-ASCII characters are
   allowed as per RFC 7997]]

9. Author's Address

   Luis Camara

   EMail: <luis.camara@live.com.pt>


Camara                  Expires January 19, 2018               [Page 26]

Internet-Draft                .0 format                        July 2017

Appendix A. Examples

   This section contains examples of data using the .0 format.

Appendix A.1. Algorithm A result example

   This is the result of encoding the JSON data:

   {"Latn": "/[A-Za-z\u00C0-\u00FF\u0100-\u017F\uFB00-\uFB06]+/",
    "Hebr": "/[\u05D0-\u05EA]+/",
    "Arab": "/[\u0600-\u06FF]+/"}

   using the .0 format.

   ".::version" is added with a value of v1.2.

    Octets
       0       1       2       3       4       5       6       7
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |                      Magic ('lm_data\0')                      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |           Mode = 1            |          Reserved2 = 0        |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |          Size = 4096          |           Count = 4           |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |          Next = 0x5C          |  Length = 20  |BufferLength=24|
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |         Buffer = 0x30         |         Value = 0x48          |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |   Type = 0xFFFFFFFF (String)  |          Length = 20          |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      '.'      |      ':'      |      ':'      |      'v'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      'e'      |      'r'      |      's'      |      'i'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      'o'      |      'n'      |       0       |       0       |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |  Length = 8   |BufferLength=12|         Buffer = 0x50         |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      'v'      |      '1'      |      '.'      |      '2'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |       0       |       0       |         Next = 0x00B4         |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |  Length = 8   |BufferLength=12|        Buffer = 0x74          |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |         Value = 0x80          |  Type = 0xFFFFFFFF (String)   |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |          Length = 52          |      'L'      |      'a'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      't'      |      'n'      |       0       |       0       |
   +-------+-------+-------+-------+-------+-------+-------+-------+

Camara                  Expires January 19, 2018               [Page 27]

Internet-Draft                .0 format                        July 2017

   (continuation)
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |  Length = 40  |BufferLength=44|        Buffer = 0x88          |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      '/'      |      '['      |      'A'      |      '-'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      'Z'      |      'a'      |      '-'      |      'z'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |   '\u00C0'    |      '-'      |   '\u00FF'    |   '\u0100'    |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      '-'      |   '\u017F'    |   '\uFB00'    |      '-'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |   '\uFB06'    |      ']'      |      '+'      |      '/'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |       0       |       0       |         Next = 0x00F4         |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |  Length = 8   |BufferLength=12|        Buffer = 0x00CC        |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |        Value = 0x00D8         |  Type = 0xFFFFFFFF (String)   |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |          Length = 28          |      'H'      |      'e'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      'b'      |      'r'      |       0       |       0       |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |  Length = 16  |BufferLength=20|        Buffer = 0x00E0        |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      '/'      |      '['      |   '\u05D0'    |      '-'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |   '\u05EA'    |      ']'      |      '+'      |      '/'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |       0       |       0       |           Next = 0            |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |  Length = 8   |BufferLength=12|        Buffer = 0x010C        |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |        Value = 0x0118         |  Type = 0xFFFFFFFF (String)   |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |          Length = 28          |      'A'      |      'r'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      'a'      |      'b'      |       0       |       0       |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |  Length = 16  |BufferLength=20|        Buffer = 0x0120        |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      '/'      |      '['      |   '\u0600'    |      '-'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |   '\u06FF'    |      ']'      |      '+'      |      '/'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |       0       |       0       |   0   |   0   |   0   |   0   |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |
   +-------+-------+-------+-------+-------+-------+-------+-------+

Camara                  Expires January 19, 2018               [Page 28]

Internet-Draft                .0 format                        July 2017

   (continuation)
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |
   .................................................................
   .................................................................
   .................................................................
   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |
   +-------+-------+-------+-------+-------+-------+-------+-------+

   (size = 4096 octets = 32768 bits)

   Base64 encoding (64 characters per line):
   bG1fZGF0YQABAAAAAAAAAAAQAAAEAAAAXAAAABQAGAAwAAAASAAAAP////8UAAAA
   LgA6ADoAdgBlAHIAcwBpAG8AbgAAAAAACAAMAFAAAAB2ADEALgAyAAAAAAC0AAAA
   CAAMAHQAAACAAAAA/////zQAAABMAGEAdABuAAAAAAAoACwAiAAAAC8AWwBBAC0A
   WgBhAC0AegDAAC0A/wAAAS0AfwEA+y0ABvtdACsALwAAAAAA9AAAAAgADADMAAAA
   2AAAAP////8cAAAASABlAGIAcgAAAAAAEAAUAOAAAAAvAFsA0AUtAOoFXQArAC8A
   AAAAAAAAAAAIAAwADAEAABgBAAD/////HAAAAEEAcgBhAGIAAAAAABAAFAAgAQAA
   LwBbAAAGLQD/Bl0AKwAvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Camara                  Expires January 19, 2018               [Page 29]

Internet-Draft                .0 format                        July 2017

   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
   AAAAAAAAAAAAAAAAAAAAAA==

Appendix A.2. Algorithm B result example

   This is the result of encoding the JSON data:

Camara                  Expires January 19, 2018               [Page 30]

Internet-Draft                .0 format                        July 2017

   {"Latn": "/[A-Za-z\u00C0-\u00FF\u0100-\u017F\uFB00-\uFB06]+/",
    "Hebr": "/[\u05D0-\u05EA]+/",
    "Arab": "/[\u0600-\u06FF]+/"}

   using the .0 format.

   ".::version" is added with a value of v1.2.

   This is the same as Appendix A.1, but using Algorithm B.

    Octets
       0       1       2       3       4       5       6       7
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |                      Magic ('lm_data\0')                      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |           Mode = 1            |          Reserved2 = 0        |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |          Size = 308           |           Count = 4           |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |          Next = 0x5C          |  Length = 20  |BufferLength=24|
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |         Buffer = 0x30         |         Value = 0x48          |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |   Type = 0xFFFFFFFF (String)  |          Length = 20          |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      '.'      |      ':'      |      ':'      |      'v'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      'e'      |      'r'      |      's'      |      'i'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      'o'      |      'n'      |       0       |       0       |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |  Length = 8   |BufferLength=12|         Buffer = 0x50         |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      'v'      |      '1'      |      '.'      |      '2'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |       0       |       0       |         Next = 0x00B4         |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |  Length = 8   |BufferLength=12|        Buffer = 0x74          |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |         Value = 0x80          |  Type = 0xFFFFFFFF (String)   |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |          Length = 52          |      'L'      |      'a'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      't'      |      'n'      |       0       |       0       |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |  Length = 40  |BufferLength=44|        Buffer = 0x88          |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      '/'      |      '['      |      'A'      |      '-'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      'Z'      |      'a'      |      '-'      |      'z'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+

Camara                  Expires January 19, 2018               [Page 31]

Internet-Draft                .0 format                        July 2017

   (continuation)
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |   '\u00C0'    |      '-'      |   '\u00FF'    |   '\u0100'    |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      '-'      |   '\u017F'    |   '\uFB00'    |      '-'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |   '\uFB06'    |      ']'      |      '+'      |      '/'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |       0       |       0       |         Next = 0x00F4         |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |  Length = 8   |BufferLength=12|        Buffer = 0x00CC        |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |        Value = 0x00D8         |  Type = 0xFFFFFFFF (String)   |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |          Length = 28          |      'H'      |      'e'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      'b'      |      'r'      |       0       |       0       |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |  Length = 16  |BufferLength=20|        Buffer = 0x00E0        |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      '/'      |      '['      |   '\u05D0'    |      '-'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |   '\u05EA'    |      ']'      |      '+'      |      '/'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |       0       |       0       |           Next = 0            |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |  Length = 8   |BufferLength=12|        Buffer = 0x010C        |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |        Value = 0x0118         |  Type = 0xFFFFFFFF (String)   |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |          Length = 28          |      'A'      |      'r'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      'a'      |      'b'      |       0       |       0       |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |  Length = 16  |BufferLength=20|        Buffer = 0x0120        |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |      '/'      |      '['      |   '\u0600'    |      '-'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |   '\u06FF'    |      ']'      |      '+'      |      '/'      |
   +-------+-------+-------+-------+-------+-------+-------+-------+
   |       0       |       0       |
   +-------+-------+-------+-------+

   (size = 308 octets = 2464 bits)

   Base64 encoding (64 characters per line):
   bG1fZGF0YQABAAAAAAAAADQBAAAEAAAAXAAAABQAGAAwAAAASAAAAP////8UAAAA
   LgA6ADoAdgBlAHIAcwBpAG8AbgAAAAAACAAMAFAAAAB2ADEALgAyAAAAAAC0AAAA
   CAAMAHQAAACAAAAA/////zQAAABMAGEAdABuAAAAAAAoACwAiAAAAC8AWwBBAC0A
   WgBhAC0AegDAAC0A/wAAAS0AfwEA+y0ABvtdACsALwAAAAAA9AAAAAgADADMAAAA
   2AAAAP////8cAAAASABlAGIAcgAAAAAAEAAUAOAAAAAvAFsA0AUtAOoFXQArAC8A

Camara                  Expires January 19, 2018               [Page 32]

Internet-Draft                .0 format                        July 2017

   AAAAAAAAAAAIAAwADAEAABgBAAD/////HAAAAEEAcgBhAGIAAAAAABAAFAAgAQAA
   LwBbAAAGLQD/Bl0AKwAvAAAAAAA=

Appendix A.3. About the examples

   The two resulting structures are .0 data encoding the same JSON
   structure. Algorithm A does not reuse strings and aligns data to 4096
   octets. Algorithm B, in the other hand, reuses strings whenever
   possible and does not align data to 4096 octets. Therefore, Algorithm
   B cannot result in larger sizes and with over 99.6% of probability
   results in smaller sizes than Algorithm A.

   String reuse was not demonstrated in the Algorithm B example, as
   there were no duplicate strings in the data (including ".::version"
   and "v1.2").

Appendix B. Writing related documents

   A good way to add examples to this specification is to create RFCs
   updating this document. No restrictions are posed on the status of
   those RFCs. For instance, best current practices for this document
   have a status of BCP and may contain examples; and documents whose
   only purpose is to provide examples have a status of Informational.

   Standards track documents designed to update the format MUST NOT be
   published in any circumstances. Best Current Practice (BCP) documents
   describing best current practices for the use of this format or
   formats using it can be written, but cannot be used to extend the
   format (See RFC 2026).

   Despite this, BCP documents can be used to provide further security
   considerations on the use of this format, and standards track
   documents can be used to provide conversions from other formats to .0
   and in the inverse direction.

Appendix C. Data leakage using a buffer underflow

   An attacker could construct .0 data that is only 124 octets, but
   claims to require a buffer of N octets in size and to contain a
   binary value of (N - 124) octets, where N is arbitrarily large.

   By sending this structure to a system not compliant with the first
   sentence of Section 7, the attacker may be able to leak up to N
   octets of data from the system, that may include sensitive
   information such as passwords, private keys, identifying information
   and credit card numbers. This assumes the system does not alter the
   data other than replacing parts of the binary value such that a
   sufficient amount of leaked data remains and sends the result as the
   response, or that it puts the original data or parts of it into the
   response.


Camara                  Expires January 19, 2018               [Page 33]

Internet-Draft                .0 format                        July 2017

   A way this vulnerability could be introduced is by allocating a
   buffer in the heap with its size indicated by the Root.Size field of
   the .0 data, without validating the .0 data and outside debug mode.

   If debug mode is used, the heap memory is normally filled with a
   distinguishing pattern. As of this writing, in Windows 7, 8 or 8.1,
   the fill pattern is 0xBAADF00D in native platform endianness. This
   can be enabled via creating/editing the GlobalFlag value in the
   Image File Execution Options registry key associated with the
   executable whose process(es) contain(s) the vulnerable implementation
   to set a flag to enable this fill pattern.

   For N > 524280, this attack does not work on Microsoft Windows when
   using the heap APIs (HeapAlloc/RtlAllocateHeap), even with a
   vulnerable implementation and outside debug mode, because, for these
   sizes, new virtual memory will be allocated, that is initialised by
   the operating system to zeroes.

   This attack could be prevented by setting the HEAP_ZERO_MEMORY
   (0x00000008) flag in the Flags argument in calls to HeapAlloc
   (Windows API) or to RtlAllocateHeap (Native API).































Camara                  Expires January 19, 2018               [Page 34]