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
//! Contains everything needed to implement Image4 properties parsing.
//!
//! # Warning
//!
//! This module exposes an implementation detail of the Image4 format and isn't very useful on its
//! own. Please use types from the [`manifest`] and [`payload`] modules if you want to parse
//! manifests or payload properties.
//!
//! # `no_alloc` API
//!
//! The `no_alloc` API expects you to drive the decoding yourself. The [`ValueRef`] type that
//! represents a value of a property only decodes values of primitive types. Data buffers are stored
//! as slices of the original decoded buffer, dictionaries and arrays are returned as the
//! [`DictRef`] and [`ArrayRef`] types which store a reference to their DER-encoded contents rather
//! than decode the actual values and store them elsewhere. Decoding the latter is possible by using
//! the iterators returned by their `.iter()` method:
//!
//! ```
//! # use image4::property::ValueDictRef;
//! # use der::Decode;
//! # fn main() -> der::Result<()> {
//! # let bytes = include_bytes!("../../tests/data/small-dict.der");
//! let dict = ValueDictRef::from_der(bytes)?;
//!
//! for result in dict.iter()? {
//! let (_tag, _value) = result?;
//! }
//! # Ok(())
//! # }
//! ```
//!
//! # `alloc` API
//!
//! The `alloc` API, unlike its `no_alloc` counterpart, has access to a memory allocator and takes
//! a different approach: it provides the [`Value`] type that decodes the property completely even
//! for complex types. Dictionaries and arrays are represented using [`BTreeMap`]s and [`Vec`]s and
//! thus are completely decoded when the property itself is decoded.
//!
//! The `alloc` feature also adds [`Dict`] and [`Array`] types that are just owned versions of
//! [`DictRef`] and [`ArrayRef`].
//!
//! # Constraints and traits
//!
//! There are three places where you can find Image4 property lists currently: manifest bodies,
//! payload properties (the `PAYP` blobs) and extensions inside X.509 certificates which are used to
//! sign the manifests. The first two contain regular plist-like values, but since the latter is
//! used to check if a certificate is allowed to sign a particular manifest it has two additional
//! values: a catch-all *"any"* value that matches anything and a *"deny"* value that disallows
//! presence of a specific tag. That allows to make certificates with fine-grained permissions while
//! ensuring that even when the key is leaked one can not use it to sign manifests for chips the
//! certificate wasn't intended to be used with. I've called properties which may take these
//! additional values *constraints*.
//!
//! *Constraints* are represented using two types similarly to regular values: [`ConstraintRef`] and
//! [`Constraint`], the first one is a `no_alloc` version another one is its `alloc` counterpart. This
//! creates a little confusion: both [`DictRef`] and [`ArrayRef`] are used by [`ValueRef`] and
//! [`ConstraintRef`] types. What should their iterators return when decoding values?
//!
//! This is solved by using generics:
//!
//! * The iterators depend on values implementing the [`DecodeProperty`] trait. It's needed to
//! restrict what types can be used as generic arguments by sealing the trait. All types
//! representing any kind of Image4 property implement it.
//! * [`DictRef`] and [`ArrayRef`] need the [`PropertyRef`] trait. Another trait is required to
//! allow easy conversion to their owned counterparts. [`ValueRef`] and [`ConstraintRef`] implement
//! this trait.
//! * [`Dict`] and [`Array`] need the [`PropertyOwned`] trait which serves the same purpose as the
//! [`PropertyRef`] trait but in the other direction. This one is implemented by [`Value`] and
//! [`Constraint`] types. These types are used more like markers in this case.
//!
//! [`BTreeMap`]: alloc::collections::BTreeMap
//! [`Vec`]: alloc::vec::Vec
//! [`manifest`]: crate::manifest
//! [`payload`]: crate::payload
pub use ;
pub use ;
pub use ;
/// An alias for a [`DictRef`] that stores regular values.
pub type ValueDictRef<'a> = ;
/// An alias for a [`DictRef`] that stores constraints.
pub type ConstraintDictRef<'a> = ;
/// An alias for a [`DictRef`] that stores regular values.
pub type ValueDict = ;
/// An alias for a [`DictRef`] that stores constraints.
pub type ConstraintDict = ;
/// An alias for an [`ArrayRef`] that stores regular values.
pub type ValueArrayRef<'a> = ;
/// An alias for an [`ArrayRef`] that stores constraints.
pub type ConstraintArrayRef<'a> = ;
/// An alias for an [`Array`] that stores regular values.
pub type ValueArray = ;
/// An alias for an [`Array`] that stores constraints.
pub type ConstraintArray = ;