1use crate::utils::{wrap_err, TinkError};
24use std::{
25 collections::{hash_map, HashMap},
26 convert::TryFrom,
27};
28
29#[derive(Clone)]
32pub struct Entry {
33 pub key_id: crate::KeyId,
34 pub primitive: crate::Primitive,
35 pub prefix: Vec<u8>,
36 pub prefix_type: tink_proto::OutputPrefixType,
37 pub status: tink_proto::KeyStatusType,
38}
39
40impl Entry {
41 fn new(
42 key_id: crate::KeyId,
43 p: crate::Primitive,
44 prefix: &[u8],
45 prefix_type: tink_proto::OutputPrefixType,
46 status: tink_proto::KeyStatusType,
47 ) -> Self {
48 Entry {
49 key_id,
50 primitive: p,
51 prefix: prefix.to_vec(),
52 prefix_type,
53 status,
54 }
55 }
56}
57
58#[derive(Clone, Default)]
69pub struct PrimitiveSet {
70 pub primary: Option<Entry>,
72
73 pub entries: HashMap<Vec<u8>, Vec<Entry>>,
77}
78
79impl PrimitiveSet {
80 pub fn new() -> Self {
82 PrimitiveSet {
83 primary: None,
84 entries: HashMap::new(),
85 }
86 }
87
88 pub fn raw_entries(&self) -> Vec<Entry> {
90 self.entries_for_prefix(&crate::cryptofmt::RAW_PREFIX)
91 }
92
93 pub fn entries_for_prefix(&self, prefix: &[u8]) -> Vec<Entry> {
95 match self.entries.get(prefix) {
96 Some(v) => v.clone(),
97 None => Vec::new(),
98 }
99 }
100
101 pub fn add(
103 &mut self,
104 p: crate::Primitive,
105 key: &tink_proto::keyset::Key,
106 ) -> Result<Entry, TinkError> {
107 if key.status != tink_proto::KeyStatusType::Enabled as i32 {
108 return Err("The key must be ENABLED".into());
109 }
110 let prefix =
111 crate::cryptofmt::output_prefix(key).map_err(|e| wrap_err("primitiveset", e))?;
112 let entry = Entry::new(
113 key.key_id,
114 p,
115 &prefix,
116 tink_proto::OutputPrefixType::try_from(key.output_prefix_type)
117 .map_err(|_e| TinkError::new("invalid key prefix type"))?,
118 tink_proto::KeyStatusType::try_from(key.status)
119 .map_err(|_e| TinkError::new("invalid key status"))?,
120 );
121 let retval = entry.clone();
122 match self.entries.entry(prefix) {
123 hash_map::Entry::Occupied(mut oe) => oe.get_mut().push(entry),
124 hash_map::Entry::Vacant(ve) => {
125 ve.insert(vec![entry]);
126 }
127 };
128 Ok(retval)
129 }
130}
131
132pub struct TypedEntry<P: From<crate::Primitive>> {
135 pub key_id: crate::KeyId,
136 pub primitive: P,
137 pub prefix: Vec<u8>,
138 pub prefix_type: tink_proto::OutputPrefixType,
139 pub status: tink_proto::KeyStatusType,
140}
141
142impl<P: From<crate::Primitive>> From<Entry> for TypedEntry<P> {
143 fn from(entry: Entry) -> Self {
144 Self {
145 key_id: entry.key_id,
146 primitive: entry.primitive.into(),
147 prefix: entry.prefix,
148 prefix_type: entry.prefix_type,
149 status: entry.status,
150 }
151 }
152}
153
154pub struct TypedPrimitiveSet<P: From<crate::Primitive>> {
157 pub primary: Option<TypedEntry<P>>,
159
160 pub entries: HashMap<Vec<u8>, Vec<TypedEntry<P>>>,
164}
165
166impl<P: From<crate::Primitive>> TypedPrimitiveSet<P> {
167 pub fn raw_entries(&self) -> Option<&Vec<TypedEntry<P>>> {
169 self.entries_for_prefix(&crate::cryptofmt::RAW_PREFIX)
170 }
171
172 pub fn entries_for_prefix(&self, prefix: &[u8]) -> Option<&Vec<TypedEntry<P>>> {
174 self.entries.get(prefix)
175 }
176}
177
178impl<T> Clone for TypedPrimitiveSet<T>
181where
182 TypedEntry<T>: Clone,
183 T: From<crate::Primitive>,
184{
185 fn clone(&self) -> Self {
186 Self {
187 primary: self.primary.as_ref().cloned(),
188 entries: self.entries.clone(),
189 }
190 }
191}
192
193impl<P: From<crate::Primitive>> From<PrimitiveSet> for TypedPrimitiveSet<P> {
196 fn from(ps: PrimitiveSet) -> Self {
197 Self {
198 primary: ps.primary.map(|e| e.into()),
199 entries: ps
200 .entries
201 .into_iter()
202 .map(|(k, v)| (k, v.into_iter().map(TypedEntry::<P>::from).collect()))
203 .collect(),
204 }
205 }
206}
207
208impl Clone for TypedEntry<Box<dyn crate::Aead>> {
213 fn clone(&self) -> Self {
214 Self {
215 key_id: self.key_id,
216 primitive: self.primitive.box_clone(),
217 prefix: self.prefix.clone(),
218 prefix_type: self.prefix_type,
219 status: self.status,
220 }
221 }
222}
223impl Clone for TypedEntry<Box<dyn crate::DeterministicAead>> {
224 fn clone(&self) -> Self {
225 Self {
226 key_id: self.key_id,
227 primitive: self.primitive.box_clone(),
228 prefix: self.prefix.clone(),
229 prefix_type: self.prefix_type,
230 status: self.status,
231 }
232 }
233}
234impl Clone for TypedEntry<Box<dyn crate::HybridDecrypt>> {
235 fn clone(&self) -> Self {
236 Self {
237 key_id: self.key_id,
238 primitive: self.primitive.box_clone(),
239 prefix: self.prefix.clone(),
240 prefix_type: self.prefix_type,
241 status: self.status,
242 }
243 }
244}
245impl Clone for TypedEntry<Box<dyn crate::HybridEncrypt>> {
246 fn clone(&self) -> Self {
247 Self {
248 key_id: self.key_id,
249 primitive: self.primitive.box_clone(),
250 prefix: self.prefix.clone(),
251 prefix_type: self.prefix_type,
252 status: self.status,
253 }
254 }
255}
256impl Clone for TypedEntry<Box<dyn crate::Mac>> {
257 fn clone(&self) -> Self {
258 Self {
259 key_id: self.key_id,
260 primitive: self.primitive.box_clone(),
261 prefix: self.prefix.clone(),
262 prefix_type: self.prefix_type,
263 status: self.status,
264 }
265 }
266}
267impl Clone for TypedEntry<Box<dyn crate::Signer>> {
268 fn clone(&self) -> Self {
269 Self {
270 key_id: self.key_id,
271 primitive: self.primitive.box_clone(),
272 prefix: self.prefix.clone(),
273 prefix_type: self.prefix_type,
274 status: self.status,
275 }
276 }
277}
278impl Clone for TypedEntry<Box<dyn crate::StreamingAead>> {
279 fn clone(&self) -> Self {
280 Self {
281 key_id: self.key_id,
282 primitive: self.primitive.box_clone(),
283 prefix: self.prefix.clone(),
284 prefix_type: self.prefix_type,
285 status: self.status,
286 }
287 }
288}
289impl Clone for TypedEntry<Box<dyn crate::Verifier>> {
290 fn clone(&self) -> Self {
291 Self {
292 key_id: self.key_id,
293 primitive: self.primitive.box_clone(),
294 prefix: self.prefix.clone(),
295 prefix_type: self.prefix_type,
296 status: self.status,
297 }
298 }
299}