- Enforce exact service and channel names with bounded failure parsing - Add hash-pinned offline notice assembly and regression coverage - Record advisory dispositions, provenance, integration evidence, and remaining gates
153 lines
9.0 KiB
Markdown
153 lines
9.0 KiB
Markdown
# Offline release notice packaging
|
|
|
|
This procedure produces a **bounded notice/provenance bundle**, not a firmware
|
|
release, corresponding-source archive, complete SBOM, or legal clearance.
|
|
The **radio-blob corresponding-source/System Library question remains open**.
|
|
See [the license inventory](dependency_licenses.md) for the original review and
|
|
[the retained scope/provenance statement](../third_party/release-notices/README.md)
|
|
for license choices, mixed notices, wolfSSH packaging discrepancy, TLSF text
|
|
assembly, icon limits, and remaining release gates.
|
|
|
|
## Run against the installed reviewed snapshot
|
|
|
|
Requirements: Python 3.9+ on Linux/POSIX with `O_NOFOLLOW`, directory descriptors
|
|
and `dir_fd` operations; already installed matching managed components,
|
|
ESP-IDF and Xtensa toolchain. Standard library only. The tool never fetches,
|
|
installs, builds, runs PlatformIO, accesses a device, or regenerates assets.
|
|
|
|
Run from the repository root. Supply **an explicit, not-yet-existing output
|
|
directory outside all three input roots**, with an existing parent. Example
|
|
for the inventory's local installation (choose a fresh final directory name):
|
|
|
|
```sh
|
|
python3 tools/release_notices.py \
|
|
--sdk-root /home/mscholz/.platformio/packages/framework-espidf \
|
|
--toolchain-root /home/mscholz/.platformio/packages/toolchain-xtensa-esp-elf \
|
|
--output /tmp/esp32-release-notices-review-01
|
|
```
|
|
|
|
`--project-root` optionally selects a different checkout containing the exact
|
|
reviewed inputs; by default it is the script's repository. The trusted catalog
|
|
always comes from the script's repository, not from that alternate checkout.
|
|
Paths to SDK/toolchain packages are explicit; no installation is guessed.
|
|
There is no user catalog option, force/overwrite mode, automatic repinning,
|
|
recursive collection, archive command, or automatic release upload.
|
|
|
|
Every input in `third_party/release-notices/inputs.json` is mandatory and pinned
|
|
by **full-file SHA-256 and size**. Missing sources, altered bytes, bad excerpts,
|
|
empty files, directories, FIFOs, symlinks (even to identical files), parent
|
|
traversal, binary notice payloads and exhausted bounds fail closed. Symlinks in
|
|
input-root or output-parent ancestry are rejected too: pass real non-symlinked
|
|
paths, not a convenience symlink. All input preflight completes before creating
|
|
output. The limits are 128 inputs, 4 MiB per input/catalog and 32 MiB cumulative
|
|
source bytes. The current catalog has 62 inputs (about 2.1 MB read and 0.51 MB
|
|
copied before the generated manifest/introduction).
|
|
|
|
An existing output file, directory (even empty) or dangling symlink is never
|
|
overwritten. Parent directories are not automatically created. Output uses
|
|
private directory/file modes (0700/0600, subject to umask). On a write failure,
|
|
the tool deliberately leaves any partial directory for inspection and never
|
|
recursively deletes it. A successful exit plus a valid manifest and matching
|
|
payload hashes is required; presence of a partial manifest is not success.
|
|
Use another fresh path for a retry. Do not put output into a tree that an
|
|
untrusted process can concurrently rename or modify; descriptor/no-follow
|
|
checks prevent symlink traversal but are not isolation from the same OS user.
|
|
|
|
## Bundle layout and reproducibility
|
|
|
|
- `README.txt`: limitations and entry point for recipients.
|
|
- `inputs/project/…`: project GPL text, resolved lock, managed licenses and
|
|
manifests, wolfSSL/wolfSSH README evidence, original wolfSSH header excerpts,
|
|
xterm MIT texts and recorded provenance, icon summary, TLSF full rendering
|
|
and scope/provenance statement.
|
|
- `inputs/sdk/…`: complete scoped SDK license documents, mixed Newlib/argtable3
|
|
notices, radio license files, package/version identity and original source
|
|
notice excerpts. SDK `LICENSE` supplies full Apache-2.0 text; it does **not**
|
|
authenticate individual icons or cover all SDK files.
|
|
- `inputs/toolchain/…`: actual toolchain Newlib text, GPLv3, GCC Runtime Library
|
|
Exception 3.1 and package identity. No toolchain executable is copied.
|
|
- `manifest.json`: schema/snapshot, catalog SHA-256, logical root/path,
|
|
full-source size/hash, optional zero-based half-open byte range, purpose,
|
|
output path/size/hash, and the generated introduction's hash. Excerpts have
|
|
`.notice.txt` appended; null ranges retain whole original files unchanged.
|
|
|
|
Whole mixed documents are preserved, not converted into guessed SPDX labels.
|
|
The longer toolchain Newlib notice does not replace the distinct SDK text.
|
|
The wolfSSH package GPLv2-or-later text and GPLv3-or-later source headers remain
|
|
separate and unmodified; upstream packaging clarification is still needed.
|
|
|
|
Generated metadata contains no collection timestamps or absolute host paths;
|
|
original notices retain their own dates and text. For identical catalog and
|
|
inputs, file names and file contents are deterministic across
|
|
output locations, input-root locations and source mtimes. Directory/file
|
|
mtimes are **not** normalized, and no reproducible tar/zip archive is claimed.
|
|
The manifest hashes all payloads but not itself; retain its hash in your
|
|
separate release evidence if needed. The catalog is trusted reviewed policy,
|
|
not a cryptographic signature or proof of package-wide integrity/authorship.
|
|
|
|
Only explicit catalog paths are read. No application config, sdkconfig,
|
|
build tree, ELF/map/binary, key, credential backup, NVS/flash dump or whole
|
|
repository is collected. Hash-pinned source implementations are read only to
|
|
validate original header excerpts, not copied as implementations. The lock and
|
|
installed package/component manifests are dependency identity metadata, not
|
|
build configuration. A hash pin is not a general-purpose secret scanner:
|
|
review additions to this trusted list before accepting them.
|
|
|
|
## Validate and inspect
|
|
|
|
Temporary-fixture regression suite (does not need installed packages):
|
|
|
|
```sh
|
|
python3 tests/release_notices/run.py
|
|
```
|
|
|
|
The suite tests missing/changed sources (including changes outside a notice
|
|
excerpt), exact mixed-text retention, byte ranges, path traversal, source/root/
|
|
output symlinks, existing user data, nonregular files, bounds, output failures,
|
|
secret/config exclusion, determinism, and CLI behavior. No hardware tests are
|
|
implied.
|
|
|
|
For a real bundle, check the successful process exit, parse `manifest.json`,
|
|
recompute every payload hash/size, check no unlisted files are present, and
|
|
read the scope statement. Compare two independently created fresh outputs by
|
|
relative names and bytes (not mtimes). Inspect at least both Newlib files,
|
|
argtable3, wpa_supplicant COPYING/README, GCC exception, wolfSSH LICENSE/README
|
|
and header excerpts, TLSF text/provenance, both xterm notices and the icon
|
|
summary. These checks establish scoped assembly, **not release compliance**.
|
|
|
|
If a pinned input differs, stop and review the changed package/license/source.
|
|
There is deliberately no update-catalog command. Review versions, new/nested
|
|
NOTICEs, original source notice ranges and hashes, then deliberately update
|
|
catalog policy and test it. The runtime does not discover added notices or
|
|
packages outside its finite list; this limitation makes its reads bounded and
|
|
prevents opportunistic collection of user files.
|
|
|
|
## Separate work before distribution
|
|
|
|
1. Resolve or obtain qualified review of radio-blob corresponding-source or
|
|
exception basis for the actual linked firmware. Apache binary permissions
|
|
alone do not settle this question. No legal clearance is claimed.
|
|
2. Resolve the wolfSSH package/header discrepancy and verify exact two-icon
|
|
provenance/licensing (recorded 7.4.47), including any applicable NOTICE.
|
|
Supplying the full Apache text is not provenance verification. No icon
|
|
assets or generated data were changed by this packaging work.
|
|
3. Audit the final application/bootloader/runtime object set and aggregation
|
|
boundaries. Full SDK/toolchain redistribution needs broader nested/tool/test
|
|
notice coverage; this is not an all-files license scanner.
|
|
4. Prepare and validate a separate, deliberately reviewed corresponding-source
|
|
delivery. Preserve exact required sources and safe build/install inputs,
|
|
asset preferred sources and scripts, original hash-matching overlay inputs,
|
|
`tools/security_overrides.py`, `cmake/security_overrides.cmake`, root CMake
|
|
integration, `cmake/wolf_crypto_policy.{cmake,h}`, and the complete
|
|
`tools/wolfssh_order/` inputs/provenance/archives. Preserve upstream notices
|
|
and generated dated change notices on eight C sources and one PUBLIC forced
|
|
header. A stock vendor tarball or this notice bundle is not sufficient.
|
|
Do not automatically archive the working repository or real configurations.
|
|
5. Assess GPLv3 source delivery/offer and User Product Installation Information.
|
|
Protect device passwords, Wi-Fi credentials, private keys, verifiers,
|
|
tickets, credential backups and flash/NVS images throughout that process.
|
|
6. Arrange and verify actual notice delivery with firmware, devices and browser
|
|
assets. This command does not add a license endpoint, change browser assets,
|
|
or prove that a recipient of a JS response or standalone device receives
|
|
notices. Keep these gates open until the real delivery path is validated.
|