Package org.webpki.cbor
CBOR - Encoder, Decoder, Signatures, and Encryption
This package contains Java support for CBOR [RFC 8949].Supported Objects
The following table shows the currently supported CBOR objects (data items) and their mapping to Java:CBOR Object | Notes | Java Mapping | Implementation |
---|---|---|---|
integer | 1 | long | CBORInt |
bignum | 1 | BigInteger | CBORBigInt |
floating point | 2 | double | CBORFloat |
byte string | byte[] | CBORBytes | |
text string | String | CBORString | |
true /false | boolean | CBORBoolean | |
null | CBORNull | ||
array | CBORArray | ||
map | CBORMap | ||
tag | CBORTag |
- The distinction between unsigned and negative values is dealt with automatically.
- 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 a value. Also see the decoderCBORDecoder.setNaNSupport(boolean)
.
This implementation does not support CBOR "simple" values beyond
true
, false
, null
, and
the three floating point variants.
Deterministic Encoding
For certain security related applications, it has been proven useful performing cryptographic operations like hashing and signatures, on "raw" CBOR data. To make this possible without additional processing, data must be in a stable form "on the wire". This can either be achieved by using the binary "as is", or through deterministic encoding. This section describes a variant of latter, making compliant CBOR systems less dependent on specific encoder and decoder designs.- RFC+: Floating point and integer objects must be treated as distinct types regardless of their numeric value. This is compliant with Rule 2 in section 4.2.2 of RFC 8949.
-
RFC: Integers, represented by the
integer
andbignum
types, must use theinteger
type if the value is between-264
and264-1
, otherwise thebignum
type must be used. The following table holds a few sample values and their proper CBOR encoding:Value Encoding 0
00
-1
20
255
18ff
256
190100
-256
38ff
-257
390100
1099511627775
1b000000ffffffffff
18446744073709551615
1bffffffffffffffff
18446744073709551616
c249010000000000000000
-18446744073709551616
3bffffffffffffffff
-18446744073709551617
c349010000000000000000
1900ff
) unless the CBOR representation offers no alternative (like1b000000ffffffffff
).Note that the integer encoding scheme above does not always return the most compact representation; the value1099511627775
(0xffffffffff
) would actually yield two bytes less using thebignum
type. -
RFC+: Floating point data must use the shortest IEEE 754
variant and associated CBOR encoding.
The following table holds floating point values needing special considerations
as well as a small set of "edge cases":
Value Encoding 0.0
f90000
-0.0
f98000
Infinity
f97c00
-Infinity
f9fc00
NaN
f97e00
Assorted Edge Cases -5.960464477539063e-8
f98001
-5.960465188081798e-8
fab3800001
65504.0
f97bff
65504.00390625
fa477fe001
65536.0
fa47800000
10.559998512268066
fa4128f5c1
10.559998512268068
fb40251eb820000001
3.4028234663852886e+38
fa7f7fffff
3.402823466385289e+38
fb47efffffe0000001
1.401298464324817e-45
fa00000001
5.0e-324
fb0000000000000001
-1.7976931348623157e+308
fbffefffffffffffff
NaN
"signaling" (likef97e01
), must be flagged as an error.Note that the shortest encoding may result in subnormal numbers likef98001
. - RFC: Map keys must be sorted in the bytewise lexicographic order of their deterministic encoding. Duplicate keys must be rejected.
-
RFC+: Since CBOR encoding according to this specification
maintains type and data uniqueness, there are no specific restrictions or
tests needed in order to determine map key equivalence.
As an example, the floating point numbers
0.0
and-0.0
, and the integer number0
represent the distinct keysf90000
,f98000
, and00
respectively. - RFC+: Deterministic CBOR according to this specification may also be provided in Diagnostic Notation.
CBORDecoder.decode(byte[])
).
For more control of the decoding process including dealing with CBOR sequences, see:
CBOR decoding options
.
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.
If the underlying CBOR data type does not match the access method
(like performing CBORObject.getInt32()
on a CBORBigInt
),
an exception is thrown.
That is, this implementation performs strict type checking.
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 (as described in section 8 of RFC 8949), is provided by theCBORObject.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.
CBOR Object | Syntax | Notes | Description |
---|---|---|---|
/ comment text / |
7 | Multi-line comment. Multi-line comments are treated as whitespace and may thus also be used between CBOR objects. | |
# comment text |
7 | 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. | |
integer |
{sign}{0b |0o |0x }n |
1, 2 |
Arbitrary sized integers without fractional components or exponents.
See CBOR integer encoding.
Binary, octal, and hexadecimal notation is 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 .
|
bignum | |||
floating point |
{sign}n. n{e± n} |
1, 2 | Floating point values must include a decimal point and an optional exponent. See CBOR floating point encoding. |
NaN | Not a number. See CBOR floating point encoding. | ||
{sign}Infinity | 2 | Infinity. See CBOR floating point encoding. | |
byte string |
h' hex data' | 3, 6 | Byte data provided in hexadecimal notation. Each byte must be represented by two hexadecimal digits. |
b64' base64 data' | 3, 6, 7 | Byte data provided in base64 or base64URL notation.
Padding with '=' characters is optional. | |
' text' | 4, 5, 7 | Byte data provided as UTF-8 encoded text. | |
<< object >> | 7 | Construct holding a CBOR object which is subsequently embedded in a byte string. | |
text string |
" text" | 4, 5 | UTF-8 encoded text string. |
true | true | Boolean value. | |
false | false | ||
null | null | Null value. | |
array | [ object ] |
Array with zero or more comma separated CBOR objects. | |
map | { key: object } |
Map with zero or more comma separated key/object pairs. Keys and objects are expressed as CBOR objects. | |
tag | n( object ) |
1 | Tag holding a CBOR object. |
, | 7 | Separator character for CBOR sequences. |
- The letter n in the Syntax column denotes one or more digits.
- The optional {sign} must be a single hyphen (
'-'
) character. - Input only: the whitespace characters
(
' '
,'\t'
,'\r'
,'\n'
) inside of string quotes are ignored. - 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. - Text strings may also include JavaScript compatible escape sequences
(
'\''
,'\"'
,'\\'
,'\b'
,'\f'
,'\n'
,'\r'
,'\t'
,'\u
hhhh'
). - Zero-length strings (
''
) return byte strings of length zero. - Input only:
the
CBORObject.toString()
method does not produce this item.
-
ClassDescriptionClass for holding CBOR
array
objects.Class for asymmetric key decryption.Decrypter engine implementation interface.Decrypter private key locator.Class for asymmetric key encryption.Class for creating CBOR asymmetric key signatures.Class for CBOR asymmetric key signature validation.Interface for dynamic key retrieval.Class for holding CBORbignum
andinteger
objects.Class for holding CBORboolean
objects.Class for holding CBORbyte string
objects.Interface holding common crypto constants.Class holding CBOR crypto support.Interface for collecting tagged or custom data.Interface for customizing map objects.Policy regarding additional CSF and CEF features.CBOR decoder class.CBORDecrypter<T extends CBORDecrypter<?>>Base class for decrypting data.Class for converting diagnostic notation CBOR to CBOR.CBOREncrypter<T extends CBOREncrypter<T>>Base class for encrypting data.Wrapper for making the WebPKI CBOR library only throw unchecked exceptions.Class for holding CBORfloating point
objects.Class for converting JSON to CBOR.Class for creating CBOR HMAC signatures.Class for CBOR HMAC signature validation.Class for holding CBORinteger
objects.Class handling Java/COSE private key conversions.Class for holding CBORmap
objects.Class for holding CBORnull
objects.Base class for all CBOR objects.Class handling Java/COSE public key conversions.Class for creating CBOR sequences.CBORSigner<T extends CBORSigner<?>>Base class for signing data.Class for holding CBORtext string
objects.Class for symmetric key decryption.Interface for dynamic key retrieval.Class for symmetric key encryption.Class for holding CBORtag
objects.Base class for typed objects decoders.Cache for typed object decoders.CBORValidator<T extends CBORValidator<T>>Base class for validating signatures.Class for X.509 decryption.Decrypter engine implementation interface.Decrypter private key locator.Class for X.509 encryption.Class for creating X.509 signatures.Class for validating X.509 signatures.Interface for verifying signature meta data.