Commit d226f55
committed
WIP: Add OCI image signing, sealing, and signature-verified mount
Implement end-to-end support for cryptographically signing composefs
OCI images using PKCS#7/fsverity detached signatures, stored as OCI
referrer artifacts following the 'composefs erofs-alongside' spec.
Core signing infrastructure (composefs crate):
- Add fsverity algorithm constants and ComposeFsAlgorithm type
- Add formatted_digest module for kernel-compatible fsverity digest
construction (the 12-byte header + raw hash used by the kernel's
FS_IOC_ENABLE_VERITY ioctl)
- Add kernel keyring support via composefs-ioctls keyring module
(inject X.509 certs into .fs-verity keyring for kernel-level
signature enforcement)
OCI signing library (composefs-oci crate):
- signing.rs: FsVeritySigningKey (sign) and FsVeritySignatureVerifier
(verify) using openssl PKCS#7 with DETACHED|BINARY|NOATTR flags,
compatible with Linux kernel fsverity builtin signature verification
- signature.rs: OCI artifact manifest builder/parser for the
'application/vnd.composefs.erofs-alongside.v1' artifact type,
storing per-layer and merged EROFS images alongside their PKCS#7
signatures as typed layers with composefs.* annotations
- image.rs: compute_per_layer_digests() and compute_merged_digest()
for deterministic EROFS image generation from OCI layer stacks
- oci_image.rs: seal_image() to compute and embed the composefs
fsverity digest into the OCI config, export/import to OCI layout
directories (migrated to ocidir crate for atomic I/O), referrer
index management
CLI commands (cfsctl):
- 'oci seal <image>' — compute composefs EROFS, embed fsverity digest
- 'oci sign <image> --cert --key' — create signature artifact
- 'oci verify <image> [--cert]' — verify signatures (digest-only
without --cert, full PKCS#7 with --cert)
- 'oci mount <name> <mountpoint> [--require-signature --trust-cert]'
— verify signatures before kernel mount
- 'oci pull ... --require-signature --trust-cert' — verify after pull
- 'oci push <image> <dest> [--signatures]' — export to OCI layout
- 'oci export-signatures <image> <dest>' — export just artifacts
- 'oci inspect' — show referrer info in JSON output
- 'keyring add-cert <pem>' — inject cert into kernel keyring
The mount and pull --require-signature paths share a common
verify_image_signatures() helper that recomputes expected EROFS
digests and verifies each PKCS#7 signature blob against the trusted
certificate.
The mount command now also resolves tag names (via OciImage::open_ref)
instead of requiring raw config digests, consistent with seal/sign/
verify.
Integration tests:
- signing.rs: 17 unprivileged tests covering sign, verify, wrong cert,
export, seal+sign roundtrip, artifact structure, --require-signature
on pull and mount
- privileged.rs: 7 tests for real fsverity enforcement, kernel keyring
injection, kernel signature acceptance/rejection
- podman.rs: 3 tests building real container images via podman
- cli.rs: updated for richer OCI test layout (4 entries) and new
oci push/roundtrip tests
- test-oci-sign-verify.sh: standalone shell-based integration tests
Assisted-by: OpenCode (Claude claude-opus-4-6)
Signed-off-by: Colin Walters <walters@verbum.org>1 parent cf5cb6a commit d226f55
File tree
26 files changed
+7004
-188
lines changed- contrib/packaging
- crates
- cfsctl
- src
- composefs-ioctls
- src
- composefs-oci
- src
- composefs/src
- fsverity
- integration-tests/src
- tests
26 files changed
+7004
-188
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
| 18 | + | |
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
34 | 35 | | |
35 | 36 | | |
36 | 37 | | |
| |||
0 commit comments