Expand description
§SUIT Validator - CBOR Manifest Parser
A NO Std Rust implementation of the SUIT (Software Updates for Internet of Things) manifest format as defined in draft-ietf-suit-manifest.
This implementation targets draft-ietf-suit-manifest-34 of the SUIT manifest specification.
§Overview
This library provides a safe, efficient CBOR decoder for SUIT manifests for IoT firmware updates and trusted invocation scenarios. It implements complete manifest structure parsing with cryptographic signature verification.
Platform Support:
no_stdCompatible: Designed for embedded systems and constrained devicesallocfeature: Optional, for enhanced debugging only
§Core Components
- Manifest Decoder: Parses CBOR-encoded SUIT structures (see
suit_decode()) - Multiple Handlers: Process decoded components with custom logic via
handler - Manifest Types: SUIT data structures defined in
suit_manifest - Error Handling: Comprehensive error types in
SuitError
§Quick Start (with default_crypto enabled)
Process a SUIT manifest with GenericStartHandler using closures:
use suit_validator::handler::GenericStartHandler;
use cose_minicbor::cose_keys::{CoseKey, CoseKeySetBuilder, KeyType, CoseAlg};
use suit_validator::crypto::CoseCrypto;
// Build trusted keys (CBOR-encoded COSE KeySet)
let mut keys_builder: CoseKeySetBuilder<1> = CoseKeySetBuilder::try_new()?;
let mut key = CoseKey::new(KeyType::Ec2);
key.alg(CoseAlg::ES256P256);
key.x(x_bytes)?;
key.y(y_bytes)?;
keys_builder.push_key(key)?;
let keys = keys_builder.into_bytes()?;
let mut crypto = CoseCrypto::new(&keys);
// Decode and process
let data = vec![/* CBOR manifest */];
let mut handler = GenericStartHandler {
on_envelope: |env| println!("Sequence: {}", env.manifest.sequence_number),
on_manifest: |_| {},
};
suit_validator::suit_decode(&data, &mut handler, &mut crypto)?;§Backend Cryptography
By default, this library uses the cose_minicbor crate as its cryptographic backend.
The default enabled features include:
"hmac"— HMAC-based signatures"decrypt"— COSE decryption support"es256"— ECDSA P-256 signatures (ES256)"sha256"— SHA-256 digest computation
The backend is automatically used when creating a CoseCrypto instance:
use suit_validator::crypto::CoseCrypto;
// `keys` is a CBOR-encoded array of COSE keys
let mut crypto = CoseCrypto::new(&keys);If you need to override the default cryptography implementation, implement the crypto::SuitCrypto trait
and pass your instance to suit_decode(). This allows using custom algorithms, hardware security modules (HSMs),
or platform-specific crypto engines.
§Custom Handler Implementation
Implement handler::SuitStartHandler, handler::SuitCommandHandler or handler::SuitSharedSequenceHandler to inspect manifests directly.
All iterators contain flat_seq::PairView objects for lazy decoding:
use suit_validator::handler::SuitCommandHandler;
use suit_validator::suit_manifest::SuitCondition;
use suit_validator::SuitError;
use suit_validator::flat_seq::PairView;
struct Inspector;
impl SuitCommandHandler for Inspector {
fn on_conditions<'a>(
&mut self,
conditions: impl Iterator<Item = PairView<'a, SuitCondition>>,
) -> Result<(), SuitError> {
for pair in conditions {
// pair.key = command code (no decode cost)
// pair.get() = decode only if needed
if pair.key == 3 {
if let Ok(cond) = pair.get() {
println!("Image match condition");
}
}
}
Ok(())
}
// ... implement other methods
}Benefits: Selective decoding, early filtering, error resilience, performance. This is the recommended pattern for manifest processing.
§Security Considerations
This library enforces critical security requirements from RFC 9124:
- Signature Verification: All manifests are cryptographically signed (Section 6.2)
- TOCTOU Protection: Digest is verified before cryptographic operations (Section 8.3)
- Rollback Protection: Sequence numbers prevent downgrade attacks
- Compatibility Checking: Vendor/class IDs must match device
See SuitError for possible error conditions.
§Handler Reference
All handlers are trait-based for flexibility, with convenient generic implementations for closure-based processing:
| Handler | Purpose | Closure Fields |
|---|---|---|
handler::SuitStartHandler | Process top-level envelope or bare manifest | N/A (implement trait) |
handler::GenericStartHandler | Closure wrapper for start handling | on_envelope, on_manifest |
handler::SuitCommandHandler | Process command sequences (fetch, install, etc.) | N/A (implement trait) |
handler::GenericCommandHandler | Closure wrapper for command sequences | on_cond, on_dir, on_custom |
handler::SuitSharedSequenceHandler | Process shared sequence metadata | N/A (implement trait) |
handler::GenericSharedSequenceHandler | Closure wrapper for shared sequences | on_cond, on_com |
Choose:
- Trait implementation for complex stateful processing with PairView inspection
- Generic handlers for simple closure-based callbacks
§References
Modules§
- crypto
- This module defines the crypto trait handler for the suit manifest processing. You can either use your own crypto backend supplying the two
- handler
- suit_
manifest - SUIT Manifest Data Structures
Structs§
Functions§
- suit_
decode - Decodes a SUIT manifest from CBOR bytes and dispatches to a handler.