1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
// We declare as error those lint warnings
// #![deny(variant_size_differences)]
// #![deny(clippy::large_enum_variant)]
//! # 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](https://datatracker.ietf.org/doc/html/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_std` Compatible**: Designed for embedded systems and constrained devices
//! - `alloc` feature: 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`](handler::GenericStartHandler) using closures:
//!
//! ```ignore
//! 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)?;
//! # Ok::<(), SuitError>(())
//! ```
//!
//! ## 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:
//!
//! ```ignore
//! 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:
//!
//! ```ignore
//! 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
//!
//! - [SUIT Manifest Specification](https://datatracker.ietf.org/doc/html/draft-ietf-suit-manifest)
//! - [SUIT Requirements (RFC 9124)](https://www.rfc-editor.org/rfc/rfc9124)
//! - [SUIT Architecture (RFC 9019)](https://www.rfc-editor.org/rfc/rfc9019)
extern crate alloc;
// modules
pub use SuitError;
/// Decodes a SUIT manifest from CBOR bytes and dispatches to a handler.
///
/// This is the primary public API for manifest processing. It handles both authenticated
/// manifests (SUIT_Envelope with COSE signatures) and bare manifests (for testing).
///
/// # Parameters
///
/// * `data` - Raw CBOR-encoded bytes containing either:
/// - SUIT_Envelope (Tag 107): Authenticated manifest with optional severable elements
/// - SUIT_Manifest (Tag 1070): Bare manifest (testing only, no signature verification)
///
/// * `handler` - Struct implementing [`handler::SuitStartHandler`] to process the decoded manifest.
/// The handler is called with either the envelope or manifest depending on the input format.
///
/// * `key_buf` - **COSE KeySet** encoded as CBOR bytes for signature verification.
/// This must be a CBOR-encoded array of COSE_Key objects (built using [`cose_minicbor::cose_keys::CoseKeySetBuilder`] as shown in [Cryptographic Signature Verification](#cryptographic-signature-verification)).
/// - **Required** for authenticated manifests (SUIT_Envelope, Tag 107)
/// - **Ignored** for bare manifests (SUIT_Manifest, Tag 1070)
/// - **Must not** be empty for authenticated manifests or `SuitError::KeysDecodeError` is returned
//
/// # Returns
///
/// * `Ok(())` - Successfully decoded and verified the manifest
/// * `Err(SuitError)` - Decoding, verification, or processing failed (see [`SuitError`] variants)
///
/// # Security Requirements
///
/// For authenticated manifests:
/// 1. CBOR decoding is performed safely with type validation
/// 2. Signature is verified against trusted keys in `key_buf`
/// 3. Digest verification occurs before cryptographic operations (TOCTOU protection)
/// 4. Handler rejects the manifest on any error
///
/// # Handler Implementation
///
/// Implement [`handler::SuitStartHandler`]:
///
/// ```ignore
/// use suit_validator::handler::*;
/// use suit_validator::suit_manifest::*;
/// use suit_validator::SuitError;
///
/// struct MyManifestProcessor;
/// impl SuitStartHandler for MyManifestProcessor {
/// fn on_envelope<'a>(&mut self, envelope: SuitEnvelope<'a>) -> Result<(), SuitError> {
/// // Process authenticated signed manifest
/// Ok(())
/// }
/// fn on_manifest<'a>(&mut self, manifest: SuitManifest<'a>) -> Result<(), SuitError> {
/// // Process bare manifest
/// Ok(())
/// }
/// }
/// ```
///
/// # References
///
/// - [SUIT Spec: Manifest Processor (Section 6)](https://datatracker.ietf.org/doc/html/draft-ietf-suit-manifest#section-6)
/// - [SUIT Spec: CBOR Encoding (Section 8)](https://datatracker.ietf.org/doc/html/draft-ietf-suit-manifest#section-8)
/// - [RFC 9124: SUIT Requirements](https://www.rfc-editor.org/rfc/rfc9124)