Package org.webpki.cbor


package org.webpki.cbor

CBOR - Encoder, Decoder, Signatures, and Encryption

This package contains Java support for CBOR using the [CBOR Core] profile.

Supported Objects

The following table shows the supported CBOR objects (data items) and their mapping to Java, here expressed in CDDL [RFC 8610] notation:
CBORImplementation Java MappingNotes
intCBORIntlong1
bigintCBORBigIntBigInteger1
floatCBORFloatdouble2
bstrCBORBytesbyte[]
tstrCBORStringString
boolCBORBooleanboolean
nullCBORNull
[]CBORArray
{}CBORMap
#6.nCBORTag
#7.nCBORSimpleint
  1. The distinction between unsigned and negative values is dealt with automatically. The encoded representation is determined by the size of the value.
  2. Floating-point data covers the 16, 32, and 64-bit IEEE 754 variants, including support for -0.0, NaN, and ±Infinity. The encoded representation is determined by the size and precision of the value. See also CBOR decoding options.

Time Data

Since CBOR lacks a native time primitive, RFC 8949 introduces such a feature through tag 0 and 1. This implementation supports these tags as well as making the same methods available without the tag constructs. For details turn to CBORTag.getDateTime(), CBORTag.getEpochTime(), CBORObject.getDateTime(), CBORObject.getEpochTime().

Deterministic Encoding

For certain security related applications, it has been proven useful performing cryptographic operations like hashing and signatures, over "raw" CBOR data. This API supports such operations through deterministic encoding which also is the default mode. The used deterministic encoding scheme is described in [CBOR Core]. If input data does not conform to the deterministic encoding scheme, a CBORException is thrown.

For more control of the decoding process, including dealing with "legacy" CBOR data as well as with CBOR sequences, see CBORDecoder(inputStream, int, int).

On output (CBORObject.encode()) deterministic encoding is always performed regardless of if CBOR data was parsed or created programmatically.

Input Data Validation

A properly designed system validates input data before acting upon it. This section describes how this can be achieved using this particular CBOR implementation.

During CBORDecoder.decode(byte[]), CBOR data is checked for well-formedness as well as by default, adhering to the determinism scheme.

After successful decoding, the CBOR data is provided as a CBORObject. For extracting the data of CBOR primitives in a Java compatible way, there are type specific access methods such as CBORObject.getInt32() and CBORObject.getString(). For accessing structured CBOR objects, the CBORObject.getMap(), CBORObject.getArray(), and CBORObject.getTag() methods, return container objects which in turn facilitate access to individual CBOR objects of the structure.

This implementation performs strict type checking. That is, if an application expects a CBOR integer and calls CBORObject.getInt32(), an exception will be thrown if the referenced object is not an instance of CBORInt, or if the CBOR integer cannot be represented as a 32-bit two-complement value.

However, you typically also want to verify that CBORMap objects do not contain unexpected keys, or that CBORArray objects contain unread elements. This can be achieved by calling CBORObject.checkForUnread(), after all expected objects have been read. This method verifies that the current CBOR object (including possible child objects), have been accessed, otherwise an exception will be thrown.

Built-in cryptographic support classes like CBORValidator and CBORPublicKey perform strict type checking as well as verifying that there are no unexpected objects inside of their respective containers.

"Schema" Support

Although this package does not support a CBOR counterpart to XML Schema, similar functionality can be achieved using the programmatic constructs described in the previous section. For an example, turn to Typed Objects.

Cryptographic Support

To aid the use of cryptography, support for Signatures and Encryption is integrated in the package.

Diagnostic Notation

Creating CBOR data in diagnostic notation is provided by the CBORObject.toString() method.

However, through the CBORDiagnosticNotation class, CBOR data may also be provided in diagnostic (textual) notation, making CBOR useful for "config" and test data files as well.

By adhering to the Deterministic Encoding specification above, CBOR data can be bidirectionally converted between its native (binary) format and diagnostic notation without getting corrupted. Note though that text-binary-text "roundtrips" do not necessarily return identical text: 0x10 used as diagnostic notation input will return 16 as diagnostic notation output. Caveat: for reliable conversions, floating-point values must be aligned with IEEE 754 encoding and rounding rules.

The following table shows how CBOR objects should be represented in diagnostic notation:
CBORSyntaxCommentNotes
/ comment text / Multi-line comment. Multi-line comments are treated as whitespace and may thus also be used between CBOR objects. 6
# comment text Single-line comment. Single-line comments are terminated by a newline character ('\n') or EOF. Single-line comments may also terminate lines holding regular CBOR items. 6
integer {sign}{0b | 0o | 0x} n Arbitrary sized integers without fractional components or exponents.
For input data in diagnostic notation, binary, octal, and hexadecimal notation is also supported by prepending numbers with 0b, 0o, and 0x respectively. The latter also permit arbitrary insertions of '_' characters between digits to enable grouping of data like 0b100_000000001.
1, 2
float {sign}n.n{e±n} Floating point values must include a decimal point and an optional exponent. 1, 2
NaN Not a number.
{sign}Infinity Infinity. 2
bstr h'hex data' Byte data provided in hexadecimal notation. Each byte must be represented by two hexadecimal digits. 3
b64'base64 data' Byte data provided in base64 or base64URL notation. Padding with '=' characters is optional. 3, 6
'text' Byte data provided as UTF-8 encoded text. 4, 5, 6
<< object... >> Construct holding zero or more comma-separated CBOR objects that are subsequently wrapped in a byte string. 6
tstr "text" UTF-8 encoded text string. 4, 5
bool true | false Boolean value.
null null Null value.
[] [ object... ] Array with zero or more comma-separated CBOR objects.
{} { key:value... } Map with zero or more comma-separated key/value pairs. Key and value pairs are expressed as CBOR objects, separated by a ':' character.
#6.nnn n( object ) Tag holding a CBOR object. 1
#7.nnn simple(n) Simple value. 1
, Separator character for CBOR sequences. 6
  1. The letter n in the Syntax column denotes one or more digits.
  2. The optional {sign} must be a single hyphen ('-') character.
  3. Input only: between the quotes, the whitespace characters (' ', '\t', '\r', '\n') are ignored.
  4. Input only: the control characters '\t' and '\n' inside of string quotes become a part of the text. For nomalizing line terminators, a single '\r' or the combination '\r\n' are rewritten as '\n'. To avoid getting newline characters ('\n') included in multi-line text strings, a line continuation marker consisting of a backslash ('\') immediately preceding the newline may be used.
  5. Text strings may also include JavaScript compatible escape sequences ('\'', '\"', '\\', '\b', '\f', '\n', '\r', '\t', '\uhhhh').
  6. Input only.