HomeISO mDOCCBOR Encoding

CBOR Encoding

Concise Binary Object Representation (CBOR) is the binary encoding format used by mDOC, offering compact representation and efficient parsing.

What is CBOR?

CBOR (Concise Binary Object Representation) is defined in RFC 8949. It's a binary data format that models data similar to JSON but encodes it more efficiently. CBOR was designed for constrained environments like IoT devices.

Compact Size

Binary encoding is 30-50% smaller than equivalent JSON, reducing bandwidth and storage.

No Base64 Needed

Binary data (signatures, keys) can be stored directly without Base64 encoding overhead.

Fast Parsing

Self-describing format allows streaming and efficient parsing on constrained devices.

Schema-less

Like JSON, CBOR doesn't require predefined schemas, enabling flexible data structures.

CBOR Data Types

CBOR defines 8 major types, each identified by the first 3 bits of the initial byte. This allows the decoder to immediately know what type of data follows.

TypeMajorExampleNotes
Unsigned Integer025 → 0x18 0x19Values 0-23 fit in one byte
Negative Integer1-1 → 0x20Encoded as -1 - n
Byte String2h'01020304'Raw binary data
Text String3"hello" → 0x65 0x68656C6C6FUTF-8 encoded
Array4[1, 2, 3]Ordered collection
Map5{1: "a", 2: "b"}Key-value pairs
Tagged Value6tag(0) datetimeSemantic tagging
Simple/Float7true, false, nullBooleans, null, floats

Encoding Format

Each CBOR data item starts with an initial byte where the high 3 bits indicate the major type and the low 5 bits provide additional information.

Initial Byte Structure

Bit layout:
MMMAAAAA
M = Major type (0-7)A = Additional info (0-31)

Example: Encoding the number 25

Major type 0 (unsigned int) = 000 binary

25 requires additional byte (values 0-23 fit in additional info, 24-255 need extra byte)

Additional info = 24 (indicates 1-byte follow) = 11000 binary

Result: 0x18 0x19 (2 bytes vs "25" = 2 bytes in JSON)

Example: Encoding a map

// JSON: {"a": 1, "b": 2}
// CBOR diagnostic: {"a": 1, "b": 2}
// CBOR hex: A2 61 61 01 61 62 02
//
// A2 = Major type 5 (map), 2 items
// 61 = Major type 3 (text), 1 byte follows
// 61 = "a" (ASCII 0x61)
// 01 = Major type 0 (uint), value 1
// 61 = text, 1 byte
// 62 = "b"
// 02 = uint, value 2

Semantic Tags

CBOR tags (major type 6) add semantic meaning to data items. mDOC uses several standard tags for dates, embedded data, and signatures.

TagMeaningExample
0Standard date/time string (ISO 8601)tag(0) "2024-01-15T10:30:00Z"
1Epoch-based date/time (Unix timestamp)tag(1) 1705316400
24Encoded CBOR data itemtag(24) h'...cbor...' (embedded CBOR)
18COSE_Sign1 (single signer)MSO signature structure
33Base64url encoding hintFor text representation
Tag 24: Embedded CBOR
Tag 24 wraps a byte string that contains CBOR. This is used heavily in mDOC to embed signed structures within larger structures.

COSE Signatures

COSE (CBOR Object Signing and Encryption) is to CBOR what JOSE is to JSON. mDOC uses COSE_Sign1 (single signer) for the MSO signature.

COSE_Sign1 Structure
COSE_Sign1 = [
  / protected /   h'a10126',      -- {1: -7} = {alg: ES256}
  / unprotected / {4: h'...'},    -- {kid: ...}
  / payload /     h'...',         -- The signed data
  / signature /   h'...'          -- ECDSA signature
]

Protected Header (decoded):
{
  1: -7    // alg: ES256 (ECDSA with P-256)
}

Common COSE Algorithms:
  -7   = ES256 (ECDSA P-256)
  -35  = ES384 (ECDSA P-384)
  -36  = ES512 (ECDSA P-521)
  -8   = EdDSA

Protected Header

CBOR-encoded map wrapped in a byte string. Contains parameters that are included in the signature calculation (alg, content type).

Unprotected Header

CBOR map with parameters not covered by signature (kid, x5chain for certificate chain).

Common COSE Header Parameters

1 (alg)Signature algorithm
4 (kid)Key identifier
33 (x5chain)X.509 certificate chain
3 (content_type)Content media type