cddl-verifier 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cddl_verifier-0.1.0/CHANGELOG.md +78 -0
- cddl_verifier-0.1.0/LICENSE +21 -0
- cddl_verifier-0.1.0/MANIFEST.in +6 -0
- cddl_verifier-0.1.0/PKG-INFO +219 -0
- cddl_verifier-0.1.0/README.md +186 -0
- cddl_verifier-0.1.0/TESTING.md +164 -0
- cddl_verifier-0.1.0/cddl-schemas/corim_test.cddl +268 -0
- cddl_verifier-0.1.0/cddl-schemas/example_iana.cddl +16 -0
- cddl_verifier-0.1.0/cddl-schemas/minimal-corim.edn +6 -0
- cddl_verifier-0.1.0/cddl-schemas/nested_iana.cddl +17 -0
- cddl_verifier-0.1.0/cddl-schemas/test_groups_choices.cddl +96 -0
- cddl_verifier-0.1.0/cddl-schemas/unified.cddl +903 -0
- cddl_verifier-0.1.0/docs/API.md +313 -0
- cddl_verifier-0.1.0/docs/CANONICAL_AND_JSON.md +572 -0
- cddl_verifier-0.1.0/docs/CBOR_BUILDER_QUICK_REF.md +215 -0
- cddl_verifier-0.1.0/docs/CBOR_DIAGNOSTIC_DUMP.md +539 -0
- cddl_verifier-0.1.0/docs/CBOR_TAG_NOTATION.md +353 -0
- cddl_verifier-0.1.0/docs/CDDL_SUPPORT.md +113 -0
- cddl_verifier-0.1.0/docs/CLI.md +118 -0
- cddl_verifier-0.1.0/docs/CORIM_SUPPORT.md +273 -0
- cddl_verifier-0.1.0/docs/EDN_FORMATTING_IMPROVEMENTS.md +351 -0
- cddl_verifier-0.1.0/docs/IANA_ANNOTATIONS_STATUS.md +183 -0
- cddl_verifier-0.1.0/docs/ITERATIVE_CONSTRUCTION.md +765 -0
- cddl_verifier-0.1.0/docs/TYPE_NAME_ANNOTATIONS.md +335 -0
- cddl_verifier-0.1.0/pyproject.toml +57 -0
- cddl_verifier-0.1.0/requirements.txt +3 -0
- cddl_verifier-0.1.0/setup.cfg +4 -0
- cddl_verifier-0.1.0/src/cddl_verifier/__init__.py +32 -0
- cddl_verifier-0.1.0/src/cddl_verifier/__main__.py +5 -0
- cddl_verifier-0.1.0/src/cddl_verifier/_analyzer.py +2764 -0
- cddl_verifier-0.1.0/src/cddl_verifier/_api.py +180 -0
- cddl_verifier-0.1.0/src/cddl_verifier/_cbor.py +1365 -0
- cddl_verifier-0.1.0/src/cddl_verifier/_json_codec.py +430 -0
- cddl_verifier-0.1.0/src/cddl_verifier/_version.py +7 -0
- cddl_verifier-0.1.0/src/cddl_verifier/cbor.py +56 -0
- cddl_verifier-0.1.0/src/cddl_verifier/cli.py +12 -0
- cddl_verifier-0.1.0/src/cddl_verifier/json_codec.py +25 -0
- cddl_verifier-0.1.0/src/cddl_verifier.egg-info/PKG-INFO +219 -0
- cddl_verifier-0.1.0/src/cddl_verifier.egg-info/SOURCES.txt +56 -0
- cddl_verifier-0.1.0/src/cddl_verifier.egg-info/dependency_links.txt +1 -0
- cddl_verifier-0.1.0/src/cddl_verifier.egg-info/entry_points.txt +2 -0
- cddl_verifier-0.1.0/src/cddl_verifier.egg-info/requires.txt +8 -0
- cddl_verifier-0.1.0/src/cddl_verifier.egg-info/top_level.txt +1 -0
- cddl_verifier-0.1.0/test-data/example_iana.cbor +1 -0
- cddl_verifier-0.1.0/test-data/minimal-corim.cbor +0 -0
- cddl_verifier-0.1.0/test-data/nested_iana.cbor +0 -0
- cddl_verifier-0.1.0/test-data/test_doc1.cbor +0 -0
- cddl_verifier-0.1.0/test-data/test_perm.cbor +0 -0
- cddl_verifier-0.1.0/tests/__init__.py +0 -0
- cddl_verifier-0.1.0/tests/conftest.py +30 -0
- cddl_verifier-0.1.0/tests/test_canonical_and_json.py +393 -0
- cddl_verifier-0.1.0/tests/test_cbor_builder.py +440 -0
- cddl_verifier-0.1.0/tests/test_cbor_cddl_analyzer.py +1659 -0
- cddl_verifier-0.1.0/tests/test_cbor_diag_dump_extra.py +137 -0
- cddl_verifier-0.1.0/tests/test_public_api.py +272 -0
- cddl_verifier-0.1.0/tests/test_set_nested.py +138 -0
- cddl_verifier-0.1.0/tests/test_simple_cbor.py +779 -0
- cddl_verifier-0.1.0/tests/test_strict_decoding.py +213 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here.
|
|
4
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the
|
|
5
|
+
project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
The version is defined once in `src/cddl_verifier/_version.py`. 0.1.0 is the first
|
|
7
|
+
public release ([#84](https://github.com/sahebbiswas/cddl_verifier/issues/84)); the section below gets its date when the release is published.
|
|
8
|
+
|
|
9
|
+
## [Unreleased] - 0.1.0
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- **Breaking:** the code is now the `cddl_verifier` package (source under
|
|
13
|
+
`src/cddl_verifier/`). The top-level modules `simple_cbor`, `cbor_json`,
|
|
14
|
+
`cbor_cddl_analyzer` and `_version` are no longer installed; their code lives
|
|
15
|
+
in the internal modules `cddl_verifier._cbor`, `._json_codec`, `._analyzer`
|
|
16
|
+
and `._version`. Use the public API below instead.
|
|
17
|
+
- `cddl-verify` now points at `cddl_verifier.cli:main`; `python -m cddl_verifier`
|
|
18
|
+
runs the same CLI. The CBOR/JSON converter runs as
|
|
19
|
+
`python -m cddl_verifier.json_codec`.
|
|
20
|
+
- Using the library no longer prints log messages: the package logger
|
|
21
|
+
(`cddl_verifier`) has only a `NullHandler`, and the CLI attaches its coloured
|
|
22
|
+
stderr handler while it runs.
|
|
23
|
+
- Package metadata: `requires-python = ">=3.9"`, classifiers, SPDX `MIT`
|
|
24
|
+
license, project URLs, `test` and `dev` extras. The unused `cbor2` extra was
|
|
25
|
+
removed; there are no runtime dependencies.
|
|
26
|
+
- **Behaviour change** from earlier unversioned code: `CBOR.load()`, `CBOR.loads()`, `cbor_decode()` and
|
|
27
|
+
`load_cbor_bytes()` now decode exactly one complete CBOR data item. Trailing
|
|
28
|
+
bytes after the item (including concatenated CBOR sequences), which were
|
|
29
|
+
previously ignored silently, are rejected with `CBORTrailingDataError`
|
|
30
|
+
([#64](https://github.com/sahebbiswas/cddl_verifier/issues/64)). The analyzer CLI and nested `.cbor` validation inherit this behaviour.
|
|
31
|
+
- Decoder errors are now `CBORDecodeError` (a `ValueError` subclass) carrying the
|
|
32
|
+
byte `offset` of the problem: `CBORTruncatedError` for empty or truncated
|
|
33
|
+
input, `CBORTrailingDataError` for trailing bytes, `CBORUnsupportedError`
|
|
34
|
+
(also a `NotImplementedError`) for indefinite-length items and `undefined`.
|
|
35
|
+
Invalid UTF-8, reserved additional-info values, duplicate map keys and
|
|
36
|
+
excessive nesting also raise `CBORDecodeError` instead of leaking
|
|
37
|
+
`UnicodeDecodeError` / `RecursionError`.
|
|
38
|
+
- Decoding accepts `bytearray` and `memoryview`; non-bytes input raises
|
|
39
|
+
`TypeError`.
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
- Validating against a root rule that is a plain primitive (`n = uint`) now
|
|
43
|
+
checks the value instead of always failing with "not a concrete type".
|
|
44
|
+
- A tagged root rule (`root = #6.501(inner)`) now requires the data to carry
|
|
45
|
+
that tag number; data with a different tag, or no tag, was accepted before.
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
- Public API ([#84](https://github.com/sahebbiswas/cddl_verifier/issues/84)):
|
|
49
|
+
`cddl_verifier.validate()`, `Validator` (with `to_edn()`), `ValidationResult`,
|
|
50
|
+
`Diagnostic` and `SchemaError`. Undecodable CBOR is reported as a `"decode"`
|
|
51
|
+
diagnostic with a byte offset instead of being raised.
|
|
52
|
+
- `cddl_verifier.cbor` (`encode`, `decode`, `diag_dump`, `CBOR`, decode errors)
|
|
53
|
+
and `cddl_verifier.json_codec` as the public CBOR and JSON helpers.
|
|
54
|
+
- `tests/test_public_api.py` for the public API and `python -m cddl_verifier`.
|
|
55
|
+
- CI builds the wheel and sdist, runs `twine check`, and runs the test suite
|
|
56
|
+
against the installed wheel on Python 3.9–3.13 and the sdist on 3.11.
|
|
57
|
+
- `MANIFEST.in`, so the sdist includes the tests, test data and docs.
|
|
58
|
+
- README: installation from PyPI, quick start, supported features, known
|
|
59
|
+
limitations (`.size` [#67](https://github.com/sahebbiswas/cddl_verifier/issues/67),
|
|
60
|
+
canonical floats [#66](https://github.com/sahebbiswas/cddl_verifier/issues/66)) and release steps.
|
|
61
|
+
- Versioning scheme: `_version.py` as the single version source, this
|
|
62
|
+
changelog, `[project]` metadata in `pyproject.toml`, and a `--version` flag.
|
|
63
|
+
- `.github/workflows/publish_pypi.yml`: builds the sdist and wheel, runs
|
|
64
|
+
`twine check`, smoke-tests both artifacts in clean environments, and
|
|
65
|
+
publishes with PyPI Trusted Publishing: to TestPyPI on manual runs, and to
|
|
66
|
+
TestPyPI then PyPI when a GitHub release is published (the only path to PyPI)
|
|
67
|
+
([#84](https://github.com/sahebbiswas/cddl_verifier/issues/84)).
|
|
68
|
+
- `pip install .` installs a `cddl-verify` console script.
|
|
69
|
+
- `docs/CLI.md`, `docs/API.md` and `docs/CDDL_SUPPORT.md` reference pages; the
|
|
70
|
+
README is now a short overview that links to them. EDN and diagnostic-dump
|
|
71
|
+
samples were regenerated from real output.
|
|
72
|
+
- `tests/test_strict_decoding.py`: regression tests for scalars, maps, arrays,
|
|
73
|
+
tags and nested data with trailing bytes, truncation at every prefix, and
|
|
74
|
+
error offsets.
|
|
75
|
+
|
|
76
|
+
### Removed
|
|
77
|
+
- `fix_indent_proper.py`, a one-off script that edited `cbor_cddl_analyzer.py`
|
|
78
|
+
in place and no longer applies to the package layout.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Saheb
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cddl-verifier
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Validate CBOR data against CDDL schemas, generate annotated EDN, and convert CBOR/JSON
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/sahebbiswas/cddl_verifier
|
|
7
|
+
Project-URL: Source, https://github.com/sahebbiswas/cddl_verifier
|
|
8
|
+
Project-URL: Issues, https://github.com/sahebbiswas/cddl_verifier/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/sahebbiswas/cddl_verifier/blob/main/CHANGELOG.md
|
|
10
|
+
Keywords: cbor,cddl,edn,rfc8610,rfc8949,corim,validation
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Topic :: Utilities
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
30
|
+
Requires-Dist: build; extra == "dev"
|
|
31
|
+
Requires-Dist: twine; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
[](https://github.com/sahebbiswas/cddl_verifier/actions/workflows/ci.yml)
|
|
35
|
+
|
|
36
|
+
# cddl-verifier
|
|
37
|
+
|
|
38
|
+
Validate CBOR (RFC 8949) data against CDDL (RFC 8610) schemas, render it as
|
|
39
|
+
annotated EDN (Extended Diagnostic Notation), and convert between CBOR and JSON.
|
|
40
|
+
It is built for attestation formats such as CoRIM and CoSWID.
|
|
41
|
+
|
|
42
|
+
> **Scope.** cddl-verifier supports a practical subset of CDDL and CBOR. It does
|
|
43
|
+
> **not** claim full RFC 8610 or RFC 8949 conformance yet; see
|
|
44
|
+
> [Limitations](#limitations) and [docs/CDDL_SUPPORT.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CDDL_SUPPORT.md).
|
|
45
|
+
|
|
46
|
+
| Surface | Name |
|
|
47
|
+
|---------|------|
|
|
48
|
+
| PyPI distribution | `cddl-verifier` |
|
|
49
|
+
| Python import package | `cddl_verifier` |
|
|
50
|
+
| Command-line tool | `cddl-verify` |
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install cddl-verifier
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Requires Python 3.9 or newer. There are no runtime dependencies: CBOR encoding
|
|
59
|
+
and decoding are bundled. Extras for contributors: `pip install "cddl-verifier[test]"`
|
|
60
|
+
(pytest) and `[dev]` (pytest, build, twine).
|
|
61
|
+
|
|
62
|
+
## Quick start
|
|
63
|
+
|
|
64
|
+
### Command line
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
cddl-verify schema.cddl data.cbor --type corim-map # validate, print annotated EDN
|
|
68
|
+
cddl-verify schema.cddl data.cbor --type corim-map --output data.edn # write EDN to a file
|
|
69
|
+
cddl-verify schema.cddl data.cbor --show-types # list the parsed CDDL types
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The exit status is `1` when the CBOR cannot be decoded or, with `--type`, when
|
|
73
|
+
validation fails. Without `--type` the first rule is used and validation errors
|
|
74
|
+
are only warnings (exit status `0`).
|
|
75
|
+
`python -m cddl_verifier` takes the same arguments. See [docs/CLI.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CLI.md).
|
|
76
|
+
|
|
77
|
+
### Python
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from pathlib import Path
|
|
81
|
+
from cddl_verifier import validate
|
|
82
|
+
|
|
83
|
+
result = validate(Path("schema.cddl"), Path("data.cbor").read_bytes(),
|
|
84
|
+
root_type="corim-map")
|
|
85
|
+
if result.valid:
|
|
86
|
+
print("valid")
|
|
87
|
+
else:
|
|
88
|
+
for diagnostic in result.diagnostics:
|
|
89
|
+
print(diagnostic.code, diagnostic.message)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- `schema` is CDDL text (`str`) or a path (`pathlib.Path`).
|
|
93
|
+
- `data` is CBOR bytes or an already-decoded Python value.
|
|
94
|
+
- `root_type` defaults to the first rule in the schema.
|
|
95
|
+
- CBOR that cannot be decoded gives an invalid result with a `"decode"`
|
|
96
|
+
diagnostic and its byte offset; it does not raise.
|
|
97
|
+
|
|
98
|
+
To check many items against one schema, or to render EDN, use `Validator`:
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from cddl_verifier import Validator
|
|
102
|
+
|
|
103
|
+
validator = Validator(Path("schema.cddl"))
|
|
104
|
+
result = validator.validate(cbor_bytes, root_type="corim-map")
|
|
105
|
+
print(validator.to_edn(cbor_bytes, root_type="corim-map"))
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
CBOR and JSON helpers:
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from cddl_verifier.cbor import encode, decode
|
|
112
|
+
from cddl_verifier.json_codec import cbor_to_json
|
|
113
|
+
|
|
114
|
+
raw = encode({0: "Alice", 1: b"\x01"}, canonical=True)
|
|
115
|
+
assert decode(raw) == {0: "Alice", 1: b"\x01"}
|
|
116
|
+
print(cbor_to_json(raw, typed=True, pretty=True))
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Decoding is strict: the input must be exactly one complete CBOR item. Empty,
|
|
120
|
+
truncated or trailing-byte input raises `CBORDecodeError` with the byte offset
|
|
121
|
+
of the problem. See [docs/API.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/API.md) for the full API.
|
|
122
|
+
|
|
123
|
+
## What is supported
|
|
124
|
+
|
|
125
|
+
- CDDL maps, arrays, type aliases, groups, type choices (`/=`), sockets (`//=`),
|
|
126
|
+
optional fields, occurrence indicators, IANA-registered parameters
|
|
127
|
+
(`&(name: n)`), CBOR tags (`#6.n(...)`), `.cbor`, `.size`, `.regexp` and
|
|
128
|
+
value-range controls on integers. Details: [docs/CDDL_SUPPORT.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CDDL_SUPPORT.md).
|
|
129
|
+
- Real CoRIM and CoSWID schemas: [docs/CORIM_SUPPORT.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CORIM_SUPPORT.md).
|
|
130
|
+
- CBOR encoding and strict decoding with byte offsets in errors; duplicate map
|
|
131
|
+
keys, invalid UTF-8 and excessive nesting are rejected.
|
|
132
|
+
- Annotated EDN output with field names from the schema.
|
|
133
|
+
- CBOR ↔ JSON conversion. `typed=True` keeps byte strings and tags, but
|
|
134
|
+
non-string map keys (such as the integer keys in CoRIM maps) still become JSON
|
|
135
|
+
strings, so maps with such keys do not round-trip exactly.
|
|
136
|
+
|
|
137
|
+
## Limitations
|
|
138
|
+
|
|
139
|
+
- **CDDL**: a practical subset, not the full RFC 8610 grammar. Malformed schemas
|
|
140
|
+
are often accepted without an error. A standards-oriented parser is planned
|
|
141
|
+
([#69](https://github.com/sahebbiswas/cddl_verifier/issues/69),
|
|
142
|
+
[#70](https://github.com/sahebbiswas/cddl_verifier/issues/70)).
|
|
143
|
+
- **`.size`**: counts characters instead of UTF-8 bytes on `tstr`, and is not
|
|
144
|
+
enforced on `uint` ([#67](https://github.com/sahebbiswas/cddl_verifier/issues/67)).
|
|
145
|
+
- **Canonical encoding**: map keys are sorted and integers are shortest-form,
|
|
146
|
+
but floats are always written as 8-byte doubles, so output is not fully RFC 8949
|
|
147
|
+
§4.2 deterministic ([#66](https://github.com/sahebbiswas/cddl_verifier/issues/66)).
|
|
148
|
+
- **CBOR**: indefinite-length items and `undefined` are not supported
|
|
149
|
+
(`CBORUnsupportedError`). CBOR sequences are rejected; a sequence API is not
|
|
150
|
+
available yet.
|
|
151
|
+
- **Value types**: tags decode to `(tag, value)` tuples and arrays or maps used
|
|
152
|
+
as map keys decode to tuples. These are provisional and expected to change
|
|
153
|
+
([#78](https://github.com/sahebbiswas/cddl_verifier/issues/78),
|
|
154
|
+
[#88](https://github.com/sahebbiswas/cddl_verifier/issues/88)).
|
|
155
|
+
|
|
156
|
+
## Documentation
|
|
157
|
+
|
|
158
|
+
| Document | Contents |
|
|
159
|
+
|----------|----------|
|
|
160
|
+
| [docs/CLI.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CLI.md) | `cddl-verify` and JSON converter options, input rules, EDN output formats |
|
|
161
|
+
| [docs/API.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/API.md) | Python API: `validate`, `Validator`, CBOR and JSON helpers |
|
|
162
|
+
| [docs/CDDL_SUPPORT.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CDDL_SUPPORT.md) | Supported CDDL syntax, types, and validation behaviour |
|
|
163
|
+
| [docs/CORIM_SUPPORT.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CORIM_SUPPORT.md) | CoRIM / CoSWID schema support |
|
|
164
|
+
| [docs/CBOR_BUILDER_QUICK_REF.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CBOR_BUILDER_QUICK_REF.md), [docs/ITERATIVE_CONSTRUCTION.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/ITERATIVE_CONSTRUCTION.md) | `CBOR` builder API in depth |
|
|
165
|
+
| [docs/CBOR_DIAGNOSTIC_DUMP.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CBOR_DIAGNOSTIC_DUMP.md) | Diagnostic dump format |
|
|
166
|
+
| [docs/CANONICAL_AND_JSON.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CANONICAL_AND_JSON.md) | Canonical encoding and JSON round-trips |
|
|
167
|
+
| [docs/](https://github.com/sahebbiswas/cddl_verifier/tree/main/docs) | EDN formatting, tag notation, and annotation notes |
|
|
168
|
+
| [TESTING.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/TESTING.md) | Running and writing tests, CI setup |
|
|
169
|
+
| [CHANGELOG.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/CHANGELOG.md) | Release history |
|
|
170
|
+
|
|
171
|
+
## Development
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
git clone https://github.com/sahebbiswas/cddl_verifier
|
|
175
|
+
cd cddl_verifier
|
|
176
|
+
pip install -e ".[test]"
|
|
177
|
+
pytest
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The package source is in `src/cddl_verifier/`. Modules whose names start with
|
|
181
|
+
an underscore are internal. See [TESTING.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/TESTING.md).
|
|
182
|
+
|
|
183
|
+
## Versioning
|
|
184
|
+
|
|
185
|
+
The project follows [Semantic Versioning 2.0.0](https://semver.org/). While the
|
|
186
|
+
major version is `0`, a minor bump (`0.x.0`) may contain breaking changes and a
|
|
187
|
+
patch bump (`0.x.y`) is for backward-compatible fixes. The stable surface is the
|
|
188
|
+
public API above (`cddl_verifier`, `cddl_verifier.cbor`,
|
|
189
|
+
`cddl_verifier.json_codec`) and the `cddl-verify` CLI; underscore modules are not
|
|
190
|
+
covered.
|
|
191
|
+
|
|
192
|
+
- The version is defined once, as `__version__` in
|
|
193
|
+
[`src/cddl_verifier/_version.py`](https://github.com/sahebbiswas/cddl_verifier/blob/main/src/cddl_verifier/_version.py).
|
|
194
|
+
`pyproject.toml` reads it, `cddl_verifier.__version__` exposes it, and
|
|
195
|
+
`cddl-verify --version` prints it. Don't repeat the version number elsewhere.
|
|
196
|
+
- A change that alters behaviour bumps the version and adds an entry to
|
|
197
|
+
[CHANGELOG.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/CHANGELOG.md) (format: [Keep a Changelog](https://keepachangelog.com/)).
|
|
198
|
+
Follow-up commits before a release go into the same, still-unreleased version.
|
|
199
|
+
- Update this README and `docs/` in the same change as the code they describe.
|
|
200
|
+
|
|
201
|
+
## Releasing
|
|
202
|
+
|
|
203
|
+
Releases go to PyPI through [`publish_pypi.yml`](https://github.com/sahebbiswas/cddl_verifier/blob/main/.github/workflows/publish_pypi.yml),
|
|
204
|
+
which uses PyPI Trusted Publishing (no API tokens are stored).
|
|
205
|
+
|
|
206
|
+
1. Set the version in `_version.py`, date its CHANGELOG section, and merge to `main`.
|
|
207
|
+
2. Optional dry run: start the workflow manually (Actions → *Publish to PyPI /
|
|
208
|
+
TestPyPI* → *Run workflow*); manual runs only upload to TestPyPI. A version can
|
|
209
|
+
only be uploaded once per index, so use a pre-release such as `0.1.1rc1` for
|
|
210
|
+
trial uploads. A release fails if its version is already on TestPyPI.
|
|
211
|
+
3. Publish a GitHub release with tag `vX.Y.Z` matching the version. The workflow
|
|
212
|
+
builds and checks the distributions, tests the wheel and sdist, uploads to
|
|
213
|
+
TestPyPI, installs from there, and then uploads to PyPI.
|
|
214
|
+
|
|
215
|
+
One-time setup: on pypi.org and test.pypi.org, add a (pending) trusted publisher
|
|
216
|
+
for repository `sahebbiswas/cddl_verifier`, workflow `publish_pypi.yml`, and
|
|
217
|
+
environment `pypi` / `testpypi` respectively (or "any" environment). GitHub
|
|
218
|
+
creates the environments on first use; add a required reviewer to `pypi` to gate
|
|
219
|
+
production uploads.
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
[](https://github.com/sahebbiswas/cddl_verifier/actions/workflows/ci.yml)
|
|
2
|
+
|
|
3
|
+
# cddl-verifier
|
|
4
|
+
|
|
5
|
+
Validate CBOR (RFC 8949) data against CDDL (RFC 8610) schemas, render it as
|
|
6
|
+
annotated EDN (Extended Diagnostic Notation), and convert between CBOR and JSON.
|
|
7
|
+
It is built for attestation formats such as CoRIM and CoSWID.
|
|
8
|
+
|
|
9
|
+
> **Scope.** cddl-verifier supports a practical subset of CDDL and CBOR. It does
|
|
10
|
+
> **not** claim full RFC 8610 or RFC 8949 conformance yet; see
|
|
11
|
+
> [Limitations](#limitations) and [docs/CDDL_SUPPORT.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CDDL_SUPPORT.md).
|
|
12
|
+
|
|
13
|
+
| Surface | Name |
|
|
14
|
+
|---------|------|
|
|
15
|
+
| PyPI distribution | `cddl-verifier` |
|
|
16
|
+
| Python import package | `cddl_verifier` |
|
|
17
|
+
| Command-line tool | `cddl-verify` |
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install cddl-verifier
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Requires Python 3.9 or newer. There are no runtime dependencies: CBOR encoding
|
|
26
|
+
and decoding are bundled. Extras for contributors: `pip install "cddl-verifier[test]"`
|
|
27
|
+
(pytest) and `[dev]` (pytest, build, twine).
|
|
28
|
+
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
### Command line
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cddl-verify schema.cddl data.cbor --type corim-map # validate, print annotated EDN
|
|
35
|
+
cddl-verify schema.cddl data.cbor --type corim-map --output data.edn # write EDN to a file
|
|
36
|
+
cddl-verify schema.cddl data.cbor --show-types # list the parsed CDDL types
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The exit status is `1` when the CBOR cannot be decoded or, with `--type`, when
|
|
40
|
+
validation fails. Without `--type` the first rule is used and validation errors
|
|
41
|
+
are only warnings (exit status `0`).
|
|
42
|
+
`python -m cddl_verifier` takes the same arguments. See [docs/CLI.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CLI.md).
|
|
43
|
+
|
|
44
|
+
### Python
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from pathlib import Path
|
|
48
|
+
from cddl_verifier import validate
|
|
49
|
+
|
|
50
|
+
result = validate(Path("schema.cddl"), Path("data.cbor").read_bytes(),
|
|
51
|
+
root_type="corim-map")
|
|
52
|
+
if result.valid:
|
|
53
|
+
print("valid")
|
|
54
|
+
else:
|
|
55
|
+
for diagnostic in result.diagnostics:
|
|
56
|
+
print(diagnostic.code, diagnostic.message)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- `schema` is CDDL text (`str`) or a path (`pathlib.Path`).
|
|
60
|
+
- `data` is CBOR bytes or an already-decoded Python value.
|
|
61
|
+
- `root_type` defaults to the first rule in the schema.
|
|
62
|
+
- CBOR that cannot be decoded gives an invalid result with a `"decode"`
|
|
63
|
+
diagnostic and its byte offset; it does not raise.
|
|
64
|
+
|
|
65
|
+
To check many items against one schema, or to render EDN, use `Validator`:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from cddl_verifier import Validator
|
|
69
|
+
|
|
70
|
+
validator = Validator(Path("schema.cddl"))
|
|
71
|
+
result = validator.validate(cbor_bytes, root_type="corim-map")
|
|
72
|
+
print(validator.to_edn(cbor_bytes, root_type="corim-map"))
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
CBOR and JSON helpers:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from cddl_verifier.cbor import encode, decode
|
|
79
|
+
from cddl_verifier.json_codec import cbor_to_json
|
|
80
|
+
|
|
81
|
+
raw = encode({0: "Alice", 1: b"\x01"}, canonical=True)
|
|
82
|
+
assert decode(raw) == {0: "Alice", 1: b"\x01"}
|
|
83
|
+
print(cbor_to_json(raw, typed=True, pretty=True))
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Decoding is strict: the input must be exactly one complete CBOR item. Empty,
|
|
87
|
+
truncated or trailing-byte input raises `CBORDecodeError` with the byte offset
|
|
88
|
+
of the problem. See [docs/API.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/API.md) for the full API.
|
|
89
|
+
|
|
90
|
+
## What is supported
|
|
91
|
+
|
|
92
|
+
- CDDL maps, arrays, type aliases, groups, type choices (`/=`), sockets (`//=`),
|
|
93
|
+
optional fields, occurrence indicators, IANA-registered parameters
|
|
94
|
+
(`&(name: n)`), CBOR tags (`#6.n(...)`), `.cbor`, `.size`, `.regexp` and
|
|
95
|
+
value-range controls on integers. Details: [docs/CDDL_SUPPORT.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CDDL_SUPPORT.md).
|
|
96
|
+
- Real CoRIM and CoSWID schemas: [docs/CORIM_SUPPORT.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CORIM_SUPPORT.md).
|
|
97
|
+
- CBOR encoding and strict decoding with byte offsets in errors; duplicate map
|
|
98
|
+
keys, invalid UTF-8 and excessive nesting are rejected.
|
|
99
|
+
- Annotated EDN output with field names from the schema.
|
|
100
|
+
- CBOR ↔ JSON conversion. `typed=True` keeps byte strings and tags, but
|
|
101
|
+
non-string map keys (such as the integer keys in CoRIM maps) still become JSON
|
|
102
|
+
strings, so maps with such keys do not round-trip exactly.
|
|
103
|
+
|
|
104
|
+
## Limitations
|
|
105
|
+
|
|
106
|
+
- **CDDL**: a practical subset, not the full RFC 8610 grammar. Malformed schemas
|
|
107
|
+
are often accepted without an error. A standards-oriented parser is planned
|
|
108
|
+
([#69](https://github.com/sahebbiswas/cddl_verifier/issues/69),
|
|
109
|
+
[#70](https://github.com/sahebbiswas/cddl_verifier/issues/70)).
|
|
110
|
+
- **`.size`**: counts characters instead of UTF-8 bytes on `tstr`, and is not
|
|
111
|
+
enforced on `uint` ([#67](https://github.com/sahebbiswas/cddl_verifier/issues/67)).
|
|
112
|
+
- **Canonical encoding**: map keys are sorted and integers are shortest-form,
|
|
113
|
+
but floats are always written as 8-byte doubles, so output is not fully RFC 8949
|
|
114
|
+
§4.2 deterministic ([#66](https://github.com/sahebbiswas/cddl_verifier/issues/66)).
|
|
115
|
+
- **CBOR**: indefinite-length items and `undefined` are not supported
|
|
116
|
+
(`CBORUnsupportedError`). CBOR sequences are rejected; a sequence API is not
|
|
117
|
+
available yet.
|
|
118
|
+
- **Value types**: tags decode to `(tag, value)` tuples and arrays or maps used
|
|
119
|
+
as map keys decode to tuples. These are provisional and expected to change
|
|
120
|
+
([#78](https://github.com/sahebbiswas/cddl_verifier/issues/78),
|
|
121
|
+
[#88](https://github.com/sahebbiswas/cddl_verifier/issues/88)).
|
|
122
|
+
|
|
123
|
+
## Documentation
|
|
124
|
+
|
|
125
|
+
| Document | Contents |
|
|
126
|
+
|----------|----------|
|
|
127
|
+
| [docs/CLI.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CLI.md) | `cddl-verify` and JSON converter options, input rules, EDN output formats |
|
|
128
|
+
| [docs/API.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/API.md) | Python API: `validate`, `Validator`, CBOR and JSON helpers |
|
|
129
|
+
| [docs/CDDL_SUPPORT.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CDDL_SUPPORT.md) | Supported CDDL syntax, types, and validation behaviour |
|
|
130
|
+
| [docs/CORIM_SUPPORT.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CORIM_SUPPORT.md) | CoRIM / CoSWID schema support |
|
|
131
|
+
| [docs/CBOR_BUILDER_QUICK_REF.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CBOR_BUILDER_QUICK_REF.md), [docs/ITERATIVE_CONSTRUCTION.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/ITERATIVE_CONSTRUCTION.md) | `CBOR` builder API in depth |
|
|
132
|
+
| [docs/CBOR_DIAGNOSTIC_DUMP.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CBOR_DIAGNOSTIC_DUMP.md) | Diagnostic dump format |
|
|
133
|
+
| [docs/CANONICAL_AND_JSON.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/docs/CANONICAL_AND_JSON.md) | Canonical encoding and JSON round-trips |
|
|
134
|
+
| [docs/](https://github.com/sahebbiswas/cddl_verifier/tree/main/docs) | EDN formatting, tag notation, and annotation notes |
|
|
135
|
+
| [TESTING.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/TESTING.md) | Running and writing tests, CI setup |
|
|
136
|
+
| [CHANGELOG.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/CHANGELOG.md) | Release history |
|
|
137
|
+
|
|
138
|
+
## Development
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
git clone https://github.com/sahebbiswas/cddl_verifier
|
|
142
|
+
cd cddl_verifier
|
|
143
|
+
pip install -e ".[test]"
|
|
144
|
+
pytest
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The package source is in `src/cddl_verifier/`. Modules whose names start with
|
|
148
|
+
an underscore are internal. See [TESTING.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/TESTING.md).
|
|
149
|
+
|
|
150
|
+
## Versioning
|
|
151
|
+
|
|
152
|
+
The project follows [Semantic Versioning 2.0.0](https://semver.org/). While the
|
|
153
|
+
major version is `0`, a minor bump (`0.x.0`) may contain breaking changes and a
|
|
154
|
+
patch bump (`0.x.y`) is for backward-compatible fixes. The stable surface is the
|
|
155
|
+
public API above (`cddl_verifier`, `cddl_verifier.cbor`,
|
|
156
|
+
`cddl_verifier.json_codec`) and the `cddl-verify` CLI; underscore modules are not
|
|
157
|
+
covered.
|
|
158
|
+
|
|
159
|
+
- The version is defined once, as `__version__` in
|
|
160
|
+
[`src/cddl_verifier/_version.py`](https://github.com/sahebbiswas/cddl_verifier/blob/main/src/cddl_verifier/_version.py).
|
|
161
|
+
`pyproject.toml` reads it, `cddl_verifier.__version__` exposes it, and
|
|
162
|
+
`cddl-verify --version` prints it. Don't repeat the version number elsewhere.
|
|
163
|
+
- A change that alters behaviour bumps the version and adds an entry to
|
|
164
|
+
[CHANGELOG.md](https://github.com/sahebbiswas/cddl_verifier/blob/main/CHANGELOG.md) (format: [Keep a Changelog](https://keepachangelog.com/)).
|
|
165
|
+
Follow-up commits before a release go into the same, still-unreleased version.
|
|
166
|
+
- Update this README and `docs/` in the same change as the code they describe.
|
|
167
|
+
|
|
168
|
+
## Releasing
|
|
169
|
+
|
|
170
|
+
Releases go to PyPI through [`publish_pypi.yml`](https://github.com/sahebbiswas/cddl_verifier/blob/main/.github/workflows/publish_pypi.yml),
|
|
171
|
+
which uses PyPI Trusted Publishing (no API tokens are stored).
|
|
172
|
+
|
|
173
|
+
1. Set the version in `_version.py`, date its CHANGELOG section, and merge to `main`.
|
|
174
|
+
2. Optional dry run: start the workflow manually (Actions → *Publish to PyPI /
|
|
175
|
+
TestPyPI* → *Run workflow*); manual runs only upload to TestPyPI. A version can
|
|
176
|
+
only be uploaded once per index, so use a pre-release such as `0.1.1rc1` for
|
|
177
|
+
trial uploads. A release fails if its version is already on TestPyPI.
|
|
178
|
+
3. Publish a GitHub release with tag `vX.Y.Z` matching the version. The workflow
|
|
179
|
+
builds and checks the distributions, tests the wheel and sdist, uploads to
|
|
180
|
+
TestPyPI, installs from there, and then uploads to PyPI.
|
|
181
|
+
|
|
182
|
+
One-time setup: on pypi.org and test.pypi.org, add a (pending) trusted publisher
|
|
183
|
+
for repository `sahebbiswas/cddl_verifier`, workflow `publish_pypi.yml`, and
|
|
184
|
+
environment `pypi` / `testpypi` respectively (or "any" environment). GitHub
|
|
185
|
+
creates the environments on first use; add a required reviewer to `pypi` to gate
|
|
186
|
+
production uploads.
|