tink_core/keyset/
manager.rs1use crate::{utils::wrap_err, KeyId, TinkError};
20use rand::Rng;
21use std::convert::TryFrom;
22use tink_proto::{KeyStatusType, OutputPrefixType};
23
24#[derive(Default)]
27pub struct Manager {
28 ks: tink_proto::Keyset,
29}
30
31impl Manager {
32 pub fn new() -> Self {
34 Self {
35 ks: tink_proto::Keyset::default(),
36 }
37 }
38
39 pub fn new_from_handle(kh: super::Handle) -> Self {
41 Self {
42 ks: kh.into_inner(),
43 }
44 }
45
46 pub fn rotate(&mut self, kt: &tink_proto::KeyTemplate) -> Result<KeyId, TinkError> {
50 self.add(kt, true)
51 }
52
53 pub fn add(
56 &mut self,
57 kt: &tink_proto::KeyTemplate,
58 as_primary: bool,
59 ) -> Result<KeyId, TinkError> {
60 let key_data = crate::registry::new_key_data(kt)
61 .map_err(|e| wrap_err("keyset::Manager: cannot create KeyData", e))?;
62 let key_id = self.new_key_id();
63 let output_prefix_type = match OutputPrefixType::try_from(kt.output_prefix_type) {
64 Err(_) | Ok(OutputPrefixType::UnknownPrefix) => {
65 return Err("keyset::Manager: unknown output prefix type".into())
66 }
67 Ok(p) => p,
68 };
69 let key = tink_proto::keyset::Key {
70 key_data: Some(key_data),
71 status: tink_proto::KeyStatusType::Enabled as i32,
72 key_id,
73 output_prefix_type: output_prefix_type as i32,
74 };
75 self.ks.key.push(key);
76 if as_primary {
77 self.ks.primary_key_id = key_id;
79 }
80 Ok(key_id)
81 }
82
83 pub fn handle(&self) -> Result<super::Handle, TinkError> {
85 super::Handle::from_keyset(self.ks.clone())
86 }
87
88 pub fn enable(&mut self, key_id: KeyId) -> Result<(), TinkError> {
92 for key in &mut self.ks.key {
93 if key.key_id == key_id {
94 return match KeyStatusType::try_from(key.status) {
95 Ok(KeyStatusType::Enabled) | Ok(KeyStatusType::Disabled) => {
96 key.status = KeyStatusType::Enabled as i32;
97 Ok(())
98 }
99 _ => Err(format!(
100 "Cannot enable key with key_id {} and status {}",
101 key_id, key.status
102 )
103 .into()),
104 };
105 }
106 }
107 Err(format!("Key {key_id} not found").into())
108 }
109
110 pub fn disable(&mut self, key_id: KeyId) -> Result<(), TinkError> {
114 if self.ks.primary_key_id == key_id {
115 return Err(format!("Cannot disable primary key (key_id {key_id})").into());
116 }
117 for key in &mut self.ks.key {
118 if key.key_id == key_id {
119 return match KeyStatusType::try_from(key.status) {
120 Ok(KeyStatusType::Enabled) | Ok(KeyStatusType::Disabled) => {
121 key.status = KeyStatusType::Disabled as i32;
122 Ok(())
123 }
124 _ => Err(format!(
125 "Cannot disable key with key_id {} and status {}",
126 key_id, key.status
127 )
128 .into()),
129 };
130 }
131 }
132 Err(format!("Key {key_id} not found").into())
133 }
134
135 pub fn destroy(&mut self, key_id: KeyId) -> Result<(), TinkError> {
140 if self.ks.primary_key_id == key_id {
141 return Err(format!("Cannot destroy primary key (key_id {key_id})").into());
142 }
143 for key in &mut self.ks.key {
144 if key.key_id == key_id {
145 return match KeyStatusType::try_from(key.status) {
146 Ok(KeyStatusType::Enabled)
147 | Ok(KeyStatusType::Disabled)
148 | Ok(KeyStatusType::Destroyed) => {
149 key.key_data = None;
150 key.status = KeyStatusType::Destroyed as i32;
151 Ok(())
152 }
153 _ => Err(format!(
154 "Cannot destroy key with key_id {} and status {}",
155 key_id, key.status
156 )
157 .into()),
158 };
159 }
160 }
161 Err(format!("Key {key_id} not found").into())
162 }
163
164 pub fn delete(&mut self, key_id: KeyId) -> Result<(), TinkError> {
167 if self.ks.primary_key_id == key_id {
168 return Err(format!("Cannot delete primary key (key_id {key_id})").into());
169 }
170 let mut idx: Option<usize> = None;
171 for (i, key) in self.ks.key.iter().enumerate() {
172 if key.key_id == key_id {
173 idx = Some(i);
174 break;
175 }
176 }
177 match idx {
178 Some(i) => {
179 self.ks.key.remove(i);
180 Ok(())
181 }
182 None => Err(format!("Key {key_id} not found").into()),
183 }
184 }
185
186 pub fn set_primary(&mut self, key_id: KeyId) -> Result<(), TinkError> {
188 for key in &self.ks.key {
189 if key.key_id == key_id {
190 return match KeyStatusType::try_from(key.status) {
191 Ok(KeyStatusType::Enabled) => {
192 self.ks.primary_key_id = key_id;
193 Ok(())
194 }
195 _ => Err(format!(
196 "The candidate (key_id {}) for the primary key must be Enabled (status {})",
197 key_id, key.status
198 )
199 .into()),
200 };
201 }
202 }
203 Err(format!("Key {key_id} not found").into())
204 }
205
206 pub fn key_count(&self) -> usize {
208 self.ks.key.len()
209 }
210
211 fn new_key_id(&self) -> KeyId {
213 let mut rng = rand::thread_rng();
214
215 loop {
216 let ret = rng.gen::<u32>();
217 if self.ks.key.iter().any(|x| x.key_id == ret) {
218 continue;
219 }
220 return ret;
221 }
222 }
223}