/src/MigTD/src/policy/src/v1/config.rs
Line | Count | Source |
1 | | // Copyright (c) 2022 Intel Corporation |
2 | | // |
3 | | // SPDX-License-Identifier: BSD-2-Clause-Patent |
4 | | |
5 | | use alloc::{collections::BTreeMap, fmt::Write, string::String, vec::Vec}; |
6 | | use core::{mem::size_of, ops, str::FromStr}; |
7 | | use serde::{ |
8 | | de::{Error, Visitor}, |
9 | | Deserialize, Deserializer, |
10 | | }; |
11 | | use td_shim_interface::td_uefi_pi::pi::guid::Guid; |
12 | | |
13 | | #[derive(Debug, Deserialize)] |
14 | | pub struct MigPolicy { |
15 | | #[serde(rename = "id", with = "guid_serde")] |
16 | | pub _id: Guid, |
17 | | #[serde(rename = "policy")] |
18 | | pub blocks: Vec<Policy>, |
19 | | } |
20 | | |
21 | | impl MigPolicy { |
22 | 0 | pub fn get_platform_info_policy(&self) -> Vec<&PlatformInfo> { |
23 | 0 | self.blocks |
24 | 0 | .iter() |
25 | 0 | .filter_map(|p| match p { |
26 | 0 | Policy::Platform(p) => Some(p), |
27 | 0 | _ => None, |
28 | 0 | }) Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_platform_info_policy::{closure#0}Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_platform_info_policy::{closure#0} |
29 | 0 | .collect() |
30 | 0 | } Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_platform_info_policy Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_platform_info_policy |
31 | | |
32 | 0 | pub fn get_qe_info_policy(&self) -> Option<&QeInfo> { |
33 | 0 | self.blocks.iter().find_map(|p| match p { |
34 | 0 | Policy::Qe(q) => Some(q), |
35 | 0 | _ => None, |
36 | 0 | }) Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_qe_info_policy::{closure#0}Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_qe_info_policy::{closure#0} |
37 | 0 | } Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_qe_info_policy Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_qe_info_policy |
38 | | |
39 | 0 | pub fn get_migtd_info_policy(&self) -> Option<&MigTdInfo> { |
40 | 0 | self.blocks.iter().find_map(|p| match p { |
41 | 0 | Policy::Migtd(m) => Some(m), |
42 | 0 | _ => None, |
43 | 0 | }) Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_migtd_info_policy::{closure#0}Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_migtd_info_policy::{closure#0} |
44 | 0 | } Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_migtd_info_policy Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_migtd_info_policy |
45 | | } |
46 | | |
47 | | #[derive(Debug, Deserialize)] |
48 | | #[serde(untagged)] |
49 | | pub enum Policy { |
50 | | Platform(PlatformInfo), |
51 | | Qe(QeInfo), |
52 | | TdxModule(TdxModuleInfo), |
53 | | Migtd(MigTdInfo), |
54 | | } |
55 | | |
56 | | #[derive(Debug, Deserialize)] |
57 | | pub struct PlatformInfo { |
58 | | pub(crate) fmspc: String, |
59 | | #[serde(rename = "Platform")] |
60 | | pub(crate) platform: Platform, |
61 | | } |
62 | | |
63 | | #[derive(Debug, Deserialize)] |
64 | | pub(crate) struct Platform { |
65 | | #[serde(rename = "TcbInfo")] |
66 | | pub(crate) tcb_info: BTreeMap<String, Property>, |
67 | | } |
68 | | |
69 | | #[derive(Debug, Deserialize)] |
70 | | pub struct QeInfo { |
71 | | #[serde(rename = "QE")] |
72 | | pub(crate) qe_identity: QeIdentity, |
73 | | } |
74 | | |
75 | | #[derive(Debug, Deserialize)] |
76 | | pub(crate) struct QeIdentity { |
77 | | #[serde(rename = "QeIdentity")] |
78 | | pub(crate) qe_identity: BTreeMap<String, Property>, |
79 | | } |
80 | | |
81 | | #[derive(Debug, Deserialize)] |
82 | | pub struct TdxModuleInfo { |
83 | | #[serde(rename = "TDXModule")] |
84 | | pub(crate) tdx_module: TdxModule, |
85 | | } |
86 | | |
87 | | #[derive(Debug, Deserialize)] |
88 | | pub(crate) struct TdxModule { |
89 | | #[serde(rename = "TDXModule_Identity")] |
90 | | pub(crate) tdx_module_identity: BTreeMap<String, Property>, |
91 | | } |
92 | | |
93 | | #[derive(Debug, Deserialize)] |
94 | | pub struct MigTdInfo { |
95 | | #[serde(rename = "MigTD")] |
96 | | pub(crate) migtd: TdInfo, |
97 | | } |
98 | | |
99 | | #[derive(Debug, Deserialize)] |
100 | | pub(crate) struct TdInfo { |
101 | | #[serde(rename = "TDINFO")] |
102 | | pub(crate) td_info: BTreeMap<String, Property>, |
103 | | #[serde(rename = "EventLog")] |
104 | | pub(crate) event_log: Option<BTreeMap<String, Property>>, |
105 | | } |
106 | | |
107 | | #[derive(Debug, Deserialize, Clone)] |
108 | | pub struct Property { |
109 | | pub(crate) operation: Operation, |
110 | | pub(crate) reference: Reference, |
111 | | } |
112 | | |
113 | | impl Property { |
114 | 0 | pub fn verify(&self, is_src: bool, local: &[u8], peer: &[u8]) -> bool { |
115 | 0 | match &self.reference { |
116 | 0 | Reference::Integer(i) => { |
117 | 0 | if peer.len() > size_of::<usize>() { |
118 | 0 | false |
119 | | } else { |
120 | 0 | let mut bytes = [0u8; size_of::<usize>()]; |
121 | 0 | bytes[..peer.len()].copy_from_slice(peer); |
122 | 0 | let peer = usize::from_le_bytes(bytes); |
123 | 0 | i.verify(is_src, &self.operation, 0, peer) |
124 | | } |
125 | | } |
126 | 0 | Reference::String(s) => { |
127 | 0 | let peer = format_bytes_hex(peer); |
128 | 0 | s.verify(is_src, &self.operation, "", &peer) |
129 | | } |
130 | 0 | Reference::Local(selfr) => selfr.verify(is_src, &self.operation, local, peer), |
131 | 0 | Reference::IntegerRange(r) => { |
132 | 0 | if peer.len() > size_of::<usize>() { |
133 | 0 | false |
134 | | } else { |
135 | 0 | let mut bytes = [0u8; size_of::<usize>()]; |
136 | 0 | bytes[..peer.len()].copy_from_slice(peer); |
137 | 0 | let peer = usize::from_le_bytes(bytes); |
138 | 0 | r.verify(is_src, &self.operation, 0, peer) |
139 | | } |
140 | | } |
141 | 0 | Reference::Array(a) => a.verify(is_src, &self.operation, &[], peer), |
142 | | } |
143 | 0 | } Unexecuted instantiation: <policy::v1::config::Property>::verify Unexecuted instantiation: <policy::v1::config::Property>::verify |
144 | | } |
145 | | |
146 | | #[derive(Debug, Clone)] |
147 | | pub(crate) enum Reference { |
148 | | Integer(Integer), |
149 | | String(RefString), |
150 | | Local(RefLocal), |
151 | | IntegerRange(IntegerRange), |
152 | | Array(Array), // TimeRange(ops::Range<usize>), |
153 | | } |
154 | | |
155 | | impl<'de> Deserialize<'de> for Reference { |
156 | 295k | fn deserialize<D>(deserializer: D) -> Result<Reference, D::Error> |
157 | 295k | where |
158 | 295k | D: Deserializer<'de>, |
159 | | { |
160 | | struct ReferenceVisitor; |
161 | | |
162 | 281k | fn parse_str(s: &str) -> Option<Reference> { |
163 | 281k | if s == "self" { |
164 | 50.6k | Some(Reference::Local(RefLocal)) |
165 | 230k | } else if let Some(range) = parse_range(s) { |
166 | 2.38k | Some(Reference::IntegerRange(IntegerRange(range))) |
167 | | } else { |
168 | 228k | Some(Reference::String(RefString(String::from_str(s).ok()?))) |
169 | | } |
170 | 281k | } Unexecuted instantiation: <policy::v1::config::Reference as serde::de::Deserialize>::deserialize::parse_str <policy::v1::config::Reference as serde::de::Deserialize>::deserialize::parse_str Line | Count | Source | 162 | 281k | fn parse_str(s: &str) -> Option<Reference> { | 163 | 281k | if s == "self" { | 164 | 50.6k | Some(Reference::Local(RefLocal)) | 165 | 230k | } else if let Some(range) = parse_range(s) { | 166 | 2.38k | Some(Reference::IntegerRange(IntegerRange(range))) | 167 | | } else { | 168 | 228k | Some(Reference::String(RefString(String::from_str(s).ok()?))) | 169 | | } | 170 | 281k | } |
|
171 | | |
172 | | impl<'de> Visitor<'de> for ReferenceVisitor { |
173 | | type Value = Reference; |
174 | | |
175 | 281k | fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> |
176 | 281k | where |
177 | 281k | E: Error, |
178 | | { |
179 | 281k | parse_str(v).ok_or(E::custom("Invalid string value")) |
180 | 281k | } Unexecuted instantiation: <<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::visit_str::<serde_json::error::Error> <<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::visit_str::<serde_json::error::Error> Line | Count | Source | 175 | 281k | fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> | 176 | 281k | where | 177 | 281k | E: Error, | 178 | | { | 179 | 281k | parse_str(v).ok_or(E::custom("Invalid string value")) | 180 | 281k | } |
|
181 | | |
182 | 5.98k | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
183 | 5.98k | where |
184 | 5.98k | E: Error, |
185 | | { |
186 | 5.98k | Ok(Reference::Integer(Integer(v as usize))) |
187 | 5.98k | } Unexecuted instantiation: <<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::visit_u64::<serde_json::error::Error> <<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::visit_u64::<serde_json::error::Error> Line | Count | Source | 182 | 5.98k | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> | 183 | 5.98k | where | 184 | 5.98k | E: Error, | 185 | | { | 186 | 5.98k | Ok(Reference::Integer(Integer(v as usize))) | 187 | 5.98k | } |
|
188 | | |
189 | 6.87k | fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> |
190 | 6.87k | where |
191 | 6.87k | A: serde::de::SeqAccess<'de>, |
192 | | { |
193 | 6.87k | let mut items = Vec::new(); |
194 | 1.78M | while let Some(val) = seq.next_element()? { |
195 | 1.77M | items.push(val); |
196 | 1.77M | } |
197 | 5.55k | Ok(Reference::Array(Array(items))) |
198 | 6.87k | } Unexecuted instantiation: <<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::visit_seq::<&mut serde::de::value::SeqDeserializer<core::iter::adapters::map::Map<core::slice::iter::Iter<serde::__private::de::content::Content>, <serde::__private::de::content::ContentRefDeserializer<serde_json::error::Error>>::new>, serde_json::error::Error>> <<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::visit_seq::<&mut serde::de::value::SeqDeserializer<core::iter::adapters::map::Map<core::slice::iter::Iter<serde::__private::de::content::Content>, <serde::__private::de::content::ContentRefDeserializer<serde_json::error::Error>>::new>, serde_json::error::Error>> Line | Count | Source | 189 | 6.87k | fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> | 190 | 6.87k | where | 191 | 6.87k | A: serde::de::SeqAccess<'de>, | 192 | | { | 193 | 6.87k | let mut items = Vec::new(); | 194 | 1.78M | while let Some(val) = seq.next_element()? { | 195 | 1.77M | items.push(val); | 196 | 1.77M | } | 197 | 5.55k | Ok(Reference::Array(Array(items))) | 198 | 6.87k | } |
|
199 | | |
200 | 1.17k | fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { |
201 | 1.17k | formatter.write_str("Expect a sequence of map or a string value") |
202 | 1.17k | } Unexecuted instantiation: <<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::expecting <<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::expecting Line | Count | Source | 200 | 1.17k | fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { | 201 | 1.17k | formatter.write_str("Expect a sequence of map or a string value") | 202 | 1.17k | } |
|
203 | | } |
204 | | |
205 | 295k | deserializer.deserialize_any(ReferenceVisitor) |
206 | 295k | } Unexecuted instantiation: <policy::v1::config::Reference as serde::de::Deserialize>::deserialize::<serde::__private::de::content::ContentRefDeserializer<serde_json::error::Error>> Unexecuted instantiation: <policy::v1::config::Reference as serde::de::Deserialize>::deserialize::<serde::__private::de::missing_field::MissingFieldDeserializer<serde_json::error::Error>> <policy::v1::config::Reference as serde::de::Deserialize>::deserialize::<serde::__private::de::content::ContentRefDeserializer<serde_json::error::Error>> Line | Count | Source | 156 | 295k | fn deserialize<D>(deserializer: D) -> Result<Reference, D::Error> | 157 | 295k | where | 158 | 295k | D: Deserializer<'de>, | 159 | | { | 160 | | struct ReferenceVisitor; | 161 | | | 162 | | fn parse_str(s: &str) -> Option<Reference> { | 163 | | if s == "self" { | 164 | | Some(Reference::Local(RefLocal)) | 165 | | } else if let Some(range) = parse_range(s) { | 166 | | Some(Reference::IntegerRange(IntegerRange(range))) | 167 | | } else { | 168 | | Some(Reference::String(RefString(String::from_str(s).ok()?))) | 169 | | } | 170 | | } | 171 | | | 172 | | impl<'de> Visitor<'de> for ReferenceVisitor { | 173 | | type Value = Reference; | 174 | | | 175 | | fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> | 176 | | where | 177 | | E: Error, | 178 | | { | 179 | | parse_str(v).ok_or(E::custom("Invalid string value")) | 180 | | } | 181 | | | 182 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> | 183 | | where | 184 | | E: Error, | 185 | | { | 186 | | Ok(Reference::Integer(Integer(v as usize))) | 187 | | } | 188 | | | 189 | | fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> | 190 | | where | 191 | | A: serde::de::SeqAccess<'de>, | 192 | | { | 193 | | let mut items = Vec::new(); | 194 | | while let Some(val) = seq.next_element()? { | 195 | | items.push(val); | 196 | | } | 197 | | Ok(Reference::Array(Array(items))) | 198 | | } | 199 | | | 200 | | fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { | 201 | | formatter.write_str("Expect a sequence of map or a string value") | 202 | | } | 203 | | } | 204 | | | 205 | 295k | deserializer.deserialize_any(ReferenceVisitor) | 206 | 295k | } |
<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::<serde::__private::de::missing_field::MissingFieldDeserializer<serde_json::error::Error>> Line | Count | Source | 156 | 207 | fn deserialize<D>(deserializer: D) -> Result<Reference, D::Error> | 157 | 207 | where | 158 | 207 | D: Deserializer<'de>, | 159 | | { | 160 | | struct ReferenceVisitor; | 161 | | | 162 | | fn parse_str(s: &str) -> Option<Reference> { | 163 | | if s == "self" { | 164 | | Some(Reference::Local(RefLocal)) | 165 | | } else if let Some(range) = parse_range(s) { | 166 | | Some(Reference::IntegerRange(IntegerRange(range))) | 167 | | } else { | 168 | | Some(Reference::String(RefString(String::from_str(s).ok()?))) | 169 | | } | 170 | | } | 171 | | | 172 | | impl<'de> Visitor<'de> for ReferenceVisitor { | 173 | | type Value = Reference; | 174 | | | 175 | | fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> | 176 | | where | 177 | | E: Error, | 178 | | { | 179 | | parse_str(v).ok_or(E::custom("Invalid string value")) | 180 | | } | 181 | | | 182 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> | 183 | | where | 184 | | E: Error, | 185 | | { | 186 | | Ok(Reference::Integer(Integer(v as usize))) | 187 | | } | 188 | | | 189 | | fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> | 190 | | where | 191 | | A: serde::de::SeqAccess<'de>, | 192 | | { | 193 | | let mut items = Vec::new(); | 194 | | while let Some(val) = seq.next_element()? { | 195 | | items.push(val); | 196 | | } | 197 | | Ok(Reference::Array(Array(items))) | 198 | | } | 199 | | | 200 | | fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { | 201 | | formatter.write_str("Expect a sequence of map or a string value") | 202 | | } | 203 | | } | 204 | | | 205 | 207 | deserializer.deserialize_any(ReferenceVisitor) | 206 | 207 | } |
|
207 | | } |
208 | | |
209 | | #[derive(Debug, PartialEq, Clone)] |
210 | | pub(crate) enum Operation { |
211 | | Equal, |
212 | | GreaterOrEqual, |
213 | | Subset, |
214 | | InRange, |
215 | | InTimeRange, |
216 | | ArrayEqual, |
217 | | ArrayGreaterOrEqual, |
218 | | } |
219 | | |
220 | | impl<'de> Deserialize<'de> for Operation { |
221 | 300k | fn deserialize<D>(deserializer: D) -> Result<Operation, D::Error> |
222 | 300k | where |
223 | 300k | D: Deserializer<'de>, |
224 | | { |
225 | 300k | let s: &str = Deserialize::deserialize(deserializer)?; |
226 | 295k | match s { |
227 | 295k | "equal" => Ok(Operation::Equal), |
228 | 32.1k | "greater-or-equal" => Ok(Operation::GreaterOrEqual), |
229 | 31.8k | "subset" => Ok(Operation::Subset), |
230 | 30.7k | "in-range" => Ok(Operation::InRange), |
231 | 29.8k | "in-time-range" => Ok(Operation::InTimeRange), |
232 | 29.4k | "array-equal" => Ok(Operation::ArrayEqual), |
233 | 3.00k | "array-greater-or-equal" => Ok(Operation::ArrayGreaterOrEqual), |
234 | 2.80k | _ => Err(D::Error::custom("Unknown operation")), |
235 | | } |
236 | 300k | } Unexecuted instantiation: <policy::v1::config::Operation as serde::de::Deserialize>::deserialize::<serde::__private::de::content::ContentRefDeserializer<serde_json::error::Error>> Unexecuted instantiation: <policy::v1::config::Operation as serde::de::Deserialize>::deserialize::<serde::__private::de::missing_field::MissingFieldDeserializer<serde_json::error::Error>> <policy::v1::config::Operation as serde::de::Deserialize>::deserialize::<serde::__private::de::content::ContentRefDeserializer<serde_json::error::Error>> Line | Count | Source | 221 | 297k | fn deserialize<D>(deserializer: D) -> Result<Operation, D::Error> | 222 | 297k | where | 223 | 297k | D: Deserializer<'de>, | 224 | | { | 225 | 297k | let s: &str = Deserialize::deserialize(deserializer)?; | 226 | 295k | match s { | 227 | 295k | "equal" => Ok(Operation::Equal), | 228 | 32.1k | "greater-or-equal" => Ok(Operation::GreaterOrEqual), | 229 | 31.8k | "subset" => Ok(Operation::Subset), | 230 | 30.7k | "in-range" => Ok(Operation::InRange), | 231 | 29.8k | "in-time-range" => Ok(Operation::InTimeRange), | 232 | 29.4k | "array-equal" => Ok(Operation::ArrayEqual), | 233 | 3.00k | "array-greater-or-equal" => Ok(Operation::ArrayGreaterOrEqual), | 234 | 2.80k | _ => Err(D::Error::custom("Unknown operation")), | 235 | | } | 236 | 297k | } |
<policy::v1::config::Operation as serde::de::Deserialize>::deserialize::<serde::__private::de::missing_field::MissingFieldDeserializer<serde_json::error::Error>> Line | Count | Source | 221 | 2.86k | fn deserialize<D>(deserializer: D) -> Result<Operation, D::Error> | 222 | 2.86k | where | 223 | 2.86k | D: Deserializer<'de>, | 224 | | { | 225 | 2.86k | let s: &str = Deserialize::deserialize(deserializer)?; | 226 | 0 | match s { | 227 | 0 | "equal" => Ok(Operation::Equal), | 228 | 0 | "greater-or-equal" => Ok(Operation::GreaterOrEqual), | 229 | 0 | "subset" => Ok(Operation::Subset), | 230 | 0 | "in-range" => Ok(Operation::InRange), | 231 | 0 | "in-time-range" => Ok(Operation::InTimeRange), | 232 | 0 | "array-equal" => Ok(Operation::ArrayEqual), | 233 | 0 | "array-greater-or-equal" => Ok(Operation::ArrayGreaterOrEqual), | 234 | 0 | _ => Err(D::Error::custom("Unknown operation")), | 235 | | } | 236 | 2.86k | } |
|
237 | | } |
238 | | |
239 | | #[derive(Debug, Clone)] |
240 | | pub(crate) struct Integer(usize); |
241 | | |
242 | | impl Integer { |
243 | 0 | fn verify(&self, _is_src: bool, op: &Operation, _local: usize, peer: usize) -> bool { |
244 | 0 | match op { |
245 | 0 | Operation::Equal => peer == self.0, |
246 | 0 | Operation::GreaterOrEqual => peer >= self.0, |
247 | 0 | _ => false, |
248 | | } |
249 | 0 | } Unexecuted instantiation: <policy::v1::config::Integer>::verify Unexecuted instantiation: <policy::v1::config::Integer>::verify |
250 | | } |
251 | | |
252 | | #[derive(Debug, Clone)] |
253 | | pub(crate) struct RefString(pub(crate) String); |
254 | | |
255 | | impl RefString { |
256 | 0 | pub(crate) fn verify(&self, _is_src: bool, op: &Operation, _local: &str, peer: &str) -> bool { |
257 | 0 | match op { |
258 | 0 | Operation::Equal => *peer == self.0, |
259 | 0 | _ => false, |
260 | | } |
261 | 0 | } Unexecuted instantiation: <policy::v1::config::RefString>::verify Unexecuted instantiation: <policy::v1::config::RefString>::verify |
262 | | } |
263 | | |
264 | | #[derive(Debug, Clone)] |
265 | | pub(crate) struct RefLocal; |
266 | | |
267 | | impl RefLocal { |
268 | 0 | fn verify(&self, is_src: bool, op: &Operation, local: &[u8], peer: &[u8]) -> bool { |
269 | 0 | if local.len() != peer.len() { |
270 | 0 | return false; |
271 | 0 | } |
272 | 0 | match op { |
273 | 0 | Operation::Equal => peer == local, |
274 | | Operation::GreaterOrEqual => { |
275 | 0 | if let Some(l) = slice_to_u64(local) { |
276 | 0 | if let Some(p) = slice_to_u64(peer) { |
277 | 0 | return if is_src { p >= l } else { l >= p }; |
278 | 0 | } |
279 | 0 | } |
280 | 0 | false |
281 | | } |
282 | 0 | Operation::ArrayEqual => local == peer, |
283 | | Operation::ArrayGreaterOrEqual => { |
284 | 0 | local |
285 | 0 | .iter() |
286 | 0 | .zip(peer.iter()) |
287 | 0 | .all(|(l, p)| if is_src { p >= l } else { l >= p })Unexecuted instantiation: <policy::v1::config::RefLocal>::verify::{closure#0}Unexecuted instantiation: <policy::v1::config::RefLocal>::verify::{closure#0} |
288 | | } |
289 | 0 | _ => false, |
290 | | } |
291 | 0 | } Unexecuted instantiation: <policy::v1::config::RefLocal>::verify Unexecuted instantiation: <policy::v1::config::RefLocal>::verify |
292 | | } |
293 | | |
294 | | #[derive(Debug, Clone)] |
295 | | pub(crate) struct IntegerRange(ops::Range<usize>); |
296 | | |
297 | | impl IntegerRange { |
298 | 0 | fn verify(&self, _is_src: bool, op: &Operation, _local: usize, peer: usize) -> bool { |
299 | 0 | match op { |
300 | 0 | Operation::InRange => self.0.contains(&peer), |
301 | 0 | Operation::InTimeRange => self.0.contains(&peer), |
302 | 0 | _ => false, |
303 | | } |
304 | 0 | } Unexecuted instantiation: <policy::v1::config::IntegerRange>::verify Unexecuted instantiation: <policy::v1::config::IntegerRange>::verify |
305 | | } |
306 | | |
307 | 230k | fn parse_range(input: &str) -> Option<ops::Range<usize>> { |
308 | 230k | let parts: Vec<&str> = input.split("..").collect(); |
309 | | |
310 | 230k | if parts.len() != 2 { |
311 | 217k | return None; |
312 | 13.0k | } |
313 | | |
314 | 13.0k | let start = if parts[0].is_empty() { |
315 | 7.74k | usize::MIN |
316 | | } else { |
317 | 5.27k | usize::from_str(parts[0]).ok()? |
318 | | }; |
319 | | |
320 | 10.7k | let end: usize = if parts[1].is_empty() { |
321 | 1.35k | usize::MAX |
322 | | } else { |
323 | 9.44k | usize::from_str(parts[1]).ok()? |
324 | | }; |
325 | | |
326 | 2.38k | Some(start..end) |
327 | 230k | } Unexecuted instantiation: policy::v1::config::parse_range policy::v1::config::parse_range Line | Count | Source | 307 | 230k | fn parse_range(input: &str) -> Option<ops::Range<usize>> { | 308 | 230k | let parts: Vec<&str> = input.split("..").collect(); | 309 | | | 310 | 230k | if parts.len() != 2 { | 311 | 217k | return None; | 312 | 13.0k | } | 313 | | | 314 | 13.0k | let start = if parts[0].is_empty() { | 315 | 7.74k | usize::MIN | 316 | | } else { | 317 | 5.27k | usize::from_str(parts[0]).ok()? | 318 | | }; | 319 | | | 320 | 10.7k | let end: usize = if parts[1].is_empty() { | 321 | 1.35k | usize::MAX | 322 | | } else { | 323 | 9.44k | usize::from_str(parts[1]).ok()? | 324 | | }; | 325 | | | 326 | 2.38k | Some(start..end) | 327 | 230k | } |
|
328 | | |
329 | | #[derive(Debug, Clone)] |
330 | | pub(crate) struct Array(Vec<u8>); |
331 | | |
332 | | impl Array { |
333 | 0 | fn verify(&self, _is_src: bool, op: &Operation, _local: &[u8], peer: &[u8]) -> bool { |
334 | 0 | if peer.len() != self.0.len() { |
335 | 0 | return false; |
336 | 0 | } |
337 | | |
338 | 0 | match op { |
339 | 0 | Operation::ArrayEqual => self.0.as_slice() == peer, |
340 | 0 | Operation::ArrayGreaterOrEqual => self.0.iter().zip(peer.iter()).all(|(r, p)| p >= r), Unexecuted instantiation: <policy::v1::config::Array>::verify::{closure#0}Unexecuted instantiation: <policy::v1::config::Array>::verify::{closure#0} |
341 | 0 | _ => false, |
342 | | } |
343 | 0 | } Unexecuted instantiation: <policy::v1::config::Array>::verify Unexecuted instantiation: <policy::v1::config::Array>::verify |
344 | | } |
345 | | |
346 | | mod guid_serde { |
347 | | use super::*; |
348 | | |
349 | 476 | pub fn deserialize<'de, D>(deserializer: D) -> Result<Guid, D::Error> |
350 | 476 | where |
351 | 476 | D: Deserializer<'de>, |
352 | | { |
353 | 476 | let s: &str = Deserialize::deserialize(deserializer)?; |
354 | 198 | Guid::from_str(s).map_err(|_| Error::custom("Invalid GUID"))Unexecuted instantiation: policy::v1::config::guid_serde::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::StrRead>>::{closure#0}policy::v1::config::guid_serde::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::SliceRead>>::{closure#0}Line | Count | Source | 354 | 104 | Guid::from_str(s).map_err(|_| Error::custom("Invalid GUID")) |
Unexecuted instantiation: policy::v1::config::guid_serde::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::StrRead>>::{closure#0} |
355 | 476 | } Unexecuted instantiation: policy::v1::config::guid_serde::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::StrRead>> policy::v1::config::guid_serde::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::SliceRead>> Line | Count | Source | 349 | 476 | pub fn deserialize<'de, D>(deserializer: D) -> Result<Guid, D::Error> | 350 | 476 | where | 351 | 476 | D: Deserializer<'de>, | 352 | | { | 353 | 476 | let s: &str = Deserialize::deserialize(deserializer)?; | 354 | 198 | Guid::from_str(s).map_err(|_| Error::custom("Invalid GUID")) | 355 | 476 | } |
Unexecuted instantiation: policy::v1::config::guid_serde::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::StrRead>> |
356 | | } |
357 | | |
358 | 0 | pub(crate) fn slice_to_u64(input: &[u8]) -> Option<u64> { |
359 | 0 | if input.len() > size_of::<u64>() { |
360 | 0 | return None; |
361 | 0 | } |
362 | 0 | let mut bytes = [0u8; 8]; |
363 | 0 | bytes[..input.len()].copy_from_slice(input); |
364 | 0 | Some(u64::from_le_bytes(bytes)) |
365 | 0 | } Unexecuted instantiation: policy::v1::config::slice_to_u64 Unexecuted instantiation: policy::v1::config::slice_to_u64 |
366 | | |
367 | 0 | pub(crate) fn format_bytes_hex(input: &[u8]) -> String { |
368 | 0 | input.iter().fold(String::new(), |mut acc, b| { |
369 | 0 | let _ = write!(acc, "{b:02X}"); |
370 | 0 | acc |
371 | 0 | }) Unexecuted instantiation: policy::v1::config::format_bytes_hex::{closure#0}Unexecuted instantiation: policy::v1::config::format_bytes_hex::{closure#0} |
372 | 0 | } Unexecuted instantiation: policy::v1::config::format_bytes_hex Unexecuted instantiation: policy::v1::config::format_bytes_hex |
373 | | |
374 | | #[cfg(test)] |
375 | | mod test { |
376 | | use super::*; |
377 | | use alloc::vec; |
378 | | |
379 | | #[test] |
380 | | fn test_policy_data() { |
381 | | use super::*; |
382 | | use serde_json; |
383 | | |
384 | | let result = serde_json::from_str::<MigPolicy>(include_str!("../../test/policy.json")); |
385 | | assert!(result.is_ok()); |
386 | | } |
387 | | |
388 | | #[test] |
389 | | fn test_policy_data_with_invalid_guid() { |
390 | | use super::*; |
391 | | use serde_json; |
392 | | |
393 | | let result = |
394 | | serde_json::from_str::<MigPolicy>(include_str!("../../test/policy_invalid_guid.json")); |
395 | | assert!(result.is_err()); |
396 | | } |
397 | | |
398 | | #[test] |
399 | | fn test_invalid_policy_data() { |
400 | | use super::*; |
401 | | use serde_json; |
402 | | |
403 | | let result = serde_json::from_str::<MigPolicy>(include_str!("../../test/policy_005.json")); |
404 | | assert!(result.is_err()); |
405 | | } |
406 | | |
407 | | #[test] |
408 | | fn test_interger_equal() { |
409 | | let equal: usize = 1; |
410 | | let not_equal: usize = 0; |
411 | | let op = Operation::Equal; |
412 | | |
413 | | assert!( |
414 | | Integer(1).verify(true, &op, 0, equal) && !Integer(1).verify(true, &op, 0, not_equal) |
415 | | ); |
416 | | } |
417 | | |
418 | | #[test] |
419 | | fn test_interger_greater_or_equal() { |
420 | | let less: usize = 0; |
421 | | let equal: usize = 1; |
422 | | let greater: usize = 2; |
423 | | |
424 | | let op = Operation::GreaterOrEqual; |
425 | | |
426 | | assert!( |
427 | | !Integer(1).verify(true, &op, 0, less) |
428 | | && Integer(1).verify(true, &op, 0, equal) |
429 | | && Integer(1).verify(true, &op, 0, greater) |
430 | | ); |
431 | | } |
432 | | |
433 | | #[test] |
434 | | fn test_string_equal() { |
435 | | let local = String::from("abc"); |
436 | | let equal = String::from("abc"); |
437 | | let not_equal = String::from("aaa"); |
438 | | let op = Operation::Equal; |
439 | | |
440 | | assert!( |
441 | | RefString(String::from("abc")).verify(true, &op, &local, &equal) |
442 | | && !RefString(String::from("abc")).verify(true, &op, &local, ¬_equal) |
443 | | ); |
444 | | } |
445 | | |
446 | | #[test] |
447 | | fn test_self_equal() { |
448 | | let local = [1, 2, 3, 4]; |
449 | | let equal = [1, 2, 3, 4]; |
450 | | let not_equal = [1, 2, 3, 4, 5]; |
451 | | |
452 | | let op = Operation::Equal; |
453 | | |
454 | | assert!( |
455 | | !RefLocal.verify(true, &op, &local, ¬_equal) |
456 | | && RefLocal.verify(true, &op, &local, &equal) |
457 | | ); |
458 | | } |
459 | | |
460 | | #[test] |
461 | | fn test_self_greater_or_equal() { |
462 | | let src = [1, 2, 3, 4]; |
463 | | let less = [1, 5, 3, 3]; |
464 | | let equal = [1, 2, 3, 4]; |
465 | | let greater = [1, 1, 3, 5]; |
466 | | |
467 | | let op = Operation::GreaterOrEqual; |
468 | | |
469 | | assert!( |
470 | | !RefLocal.verify(true, &op, &src, &less) |
471 | | && RefLocal.verify(true, &op, &src, &equal) |
472 | | && RefLocal.verify(true, &op, &src, &greater) |
473 | | ); |
474 | | |
475 | | let dst = src; |
476 | | assert!( |
477 | | RefLocal.verify(false, &op, &dst, &less) |
478 | | && RefLocal.verify(false, &op, &dst, &equal) |
479 | | && !RefLocal.verify(false, &op, &dst, &greater) |
480 | | ); |
481 | | } |
482 | | |
483 | | #[test] |
484 | | fn test_self_array_equal() { |
485 | | let src = [1, 2, 3, 4]; |
486 | | let equal = [1, 2, 3, 4]; |
487 | | let unequal = [1, 2, 3, 5]; |
488 | | |
489 | | let op = Operation::ArrayEqual; |
490 | | |
491 | | assert!( |
492 | | !RefLocal.verify(true, &op, &src, &unequal) && RefLocal.verify(true, &op, &src, &equal) |
493 | | ); |
494 | | } |
495 | | |
496 | | #[test] |
497 | | fn test_self_array_greater_or_equal() { |
498 | | let src = [1, 2, 3, 4]; |
499 | | let less1 = [1, 3, 3, 3]; |
500 | | let less2 = [1, 1, 3, 3]; |
501 | | let equal = [1, 2, 3, 4]; |
502 | | let greater = [1, 2, 3, 5]; |
503 | | |
504 | | let op = Operation::ArrayGreaterOrEqual; |
505 | | |
506 | | assert!( |
507 | | !RefLocal.verify(true, &op, &src, &less1) |
508 | | && !RefLocal.verify(true, &op, &src, &less2) |
509 | | && RefLocal.verify(true, &op, &src, &equal) |
510 | | && RefLocal.verify(true, &op, &src, &greater) |
511 | | ); |
512 | | |
513 | | let dst = src; |
514 | | assert!( |
515 | | !RefLocal.verify(false, &op, &dst, &less1) |
516 | | && RefLocal.verify(false, &op, &dst, &less2) |
517 | | && RefLocal.verify(false, &op, &dst, &equal) |
518 | | && !RefLocal.verify(false, &op, &dst, &greater) |
519 | | ); |
520 | | } |
521 | | |
522 | | #[test] |
523 | | fn test_interrange_inrange() { |
524 | | let inrange = 2; |
525 | | let not_inrange = 3; |
526 | | |
527 | | let op = Operation::InRange; |
528 | | |
529 | | assert!( |
530 | | !IntegerRange(0..3).verify(true, &op, 0, not_inrange) |
531 | | && IntegerRange(0..3).verify(true, &op, 0, inrange) |
532 | | ); |
533 | | } |
534 | | |
535 | | #[test] |
536 | | fn test_array_equal() { |
537 | | let reference = vec![0x2, 0x60, 0x6a]; |
538 | | let local = &[]; |
539 | | let equal = &[0x2, 0x60, 0x6a]; |
540 | | let greater = &[0x2, 0x60, 0x6c]; |
541 | | let smaller = &[0x2, 0x5f, 0x6a]; |
542 | | let invalid = &[0x2, 0x60, 0x6a, 0x1]; |
543 | | let op = Operation::ArrayEqual; |
544 | | |
545 | | assert!( |
546 | | Array(reference.clone()).verify(true, &op, local, equal) |
547 | | && !Array(reference.clone()).verify(true, &op, local, greater) |
548 | | && !Array(reference.clone()).verify(true, &op, local, smaller) |
549 | | && !Array(reference.clone()).verify(true, &op, local, invalid) |
550 | | ); |
551 | | } |
552 | | |
553 | | #[test] |
554 | | fn test_array_greater_or_equal() { |
555 | | let reference = vec![0x2, 0x60, 0x6a]; |
556 | | let local = &[]; |
557 | | let equal = &[0x2, 0x60, 0x6a]; |
558 | | let greater = &[0x2, 0x61, 0x6a]; |
559 | | let smaller = &[0x3, 0x60, 0x60]; |
560 | | let op = Operation::ArrayGreaterOrEqual; |
561 | | |
562 | | assert!( |
563 | | Array(reference.clone()).verify(true, &op, local, equal) |
564 | | && Array(reference.clone()).verify(true, &op, local, greater) |
565 | | && !Array(reference.clone()).verify(true, &op, local, smaller) |
566 | | ); |
567 | | } |
568 | | } |