parsec_service/key_info_managers/
mod.rs

1// Copyright 2019 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3//! Persistent mapping between key identities and key information
4//!
5//! This module declares a [`ManageKeyInfo`](https://parallaxsecond.github.io/parsec-book/parsec_service/key_info_managers.html)
6//! trait to help providers to store in a persistent manner the mapping between the name and the
7//! information of the keys they manage. Different implementors might store this mapping using different
8//! means but it has to be persistent.
9use crate::authenticators::ApplicationIdentity;
10#[allow(deprecated)]
11use crate::key_info_managers::on_disk_manager::KeyTriple;
12use crate::providers::ProviderIdentity;
13use crate::utils::config::{KeyInfoManagerConfig, KeyInfoManagerType};
14use anyhow::Result;
15use derivative::Derivative;
16use parsec_interface::operations::psa_key_attributes::Attributes;
17use parsec_interface::requests::{AuthType, ResponseStatus};
18use serde::de::DeserializeOwned;
19use serde::{Deserialize, Serialize};
20use std::convert::TryFrom;
21use std::fmt;
22use std::hash::{Hash, Hasher};
23use std::sync::{Arc, RwLock};
24use zeroize::Zeroize;
25
26pub mod on_disk_manager;
27pub mod sqlite_manager;
28
29/// This structure corresponds to a unique identifier of the key. It is used internally by the Key
30/// ID manager to refer to a key.
31/// Note: for equality and hashing, key identity structs with matching ApplicationIdentity and key_name
32/// are considered equal; ProviderIdentity is not considered when evaluating equality or the hash.
33#[derive(Debug, Clone)]
34pub struct KeyIdentity {
35    /// The identity of the application that created the key.
36    application: ApplicationIdentity,
37    /// The identity of the provider where the key is stored.
38    provider: ProviderIdentity,
39    /// The key name
40    key_name: String,
41}
42
43impl Hash for KeyIdentity {
44    fn hash<H: Hasher>(&self, state: &mut H) {
45        self.application.hash(state);
46        self.key_name.hash(state);
47    }
48}
49
50impl PartialEq for KeyIdentity {
51    fn eq(&self, other: &Self) -> bool {
52        self.key_name() == other.key_name() && self.application() == other.application()
53    }
54}
55
56impl Eq for KeyIdentity {}
57
58impl fmt::Display for KeyIdentity {
59    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60        write!(
61            f,
62            "KeyIdentity: {{\n{},\n{},\nkey_name: \"{}\",\n}}",
63            self.application, self.provider, self.key_name
64        )
65    }
66}
67
68/// Information stored about a key
69#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Zeroize)]
70#[zeroize(drop)]
71struct KeyInfo {
72    /// Reference to a key in the Provider
73    id: Vec<u8>,
74    /// Attributes of a key
75    attributes: Attributes,
76}
77
78impl KeyIdentity {
79    /// Creates a new instance of KeyIdentity.
80    pub fn new(
81        application: ApplicationIdentity,
82        provider: ProviderIdentity,
83        key_name: String,
84    ) -> KeyIdentity {
85        KeyIdentity {
86            application,
87            provider,
88            key_name,
89        }
90    }
91
92    /// Checks if this key belongs to a specific provider.
93    pub fn belongs_to_provider(&self, provider_identity: &ProviderIdentity) -> bool {
94        self.provider().name() == provider_identity.name()
95            && self.provider().uuid() == provider_identity.uuid()
96    }
97
98    /// Get the key name
99    pub fn key_name(&self) -> &String {
100        &self.key_name
101    }
102
103    /// Get the application identity of the key
104    pub fn application(&self) -> &ApplicationIdentity {
105        &self.application
106    }
107
108    /// Get the provider identity of the key
109    pub fn provider(&self) -> &ProviderIdentity {
110        &self.provider
111    }
112}
113
114/// Converts the error string returned by the ManageKeyInfo methods to
115/// ResponseStatus::KeyInfoManagerError.
116pub fn to_response_status(error_string: String) -> ResponseStatus {
117    format_error!(
118        "Converting error to ResponseStatus:KeyInfoManagerError",
119        error_string
120    );
121    ResponseStatus::KeyInfoManagerError
122}
123
124/// Management interface for key name to key info mapping
125///
126/// Interface to be implemented for persistent storage of key name -> key info mappings.
127trait ManageKeyInfo {
128    /// Returns the key info manager type.
129    fn key_info_manager_type(&self) -> KeyInfoManagerType;
130
131    /// Returns a reference to the key info corresponding to this KeyIdentity or `None` if it does not
132    /// exist.
133    ///
134    /// # Errors
135    ///
136    /// Returns an error as a String if there was a problem accessing the Key Info Manager.
137    fn get(&self, key_identity: &KeyIdentity) -> Result<Option<&KeyInfo>, String>;
138
139    /// Returns a Vec of reference to the key identities corresponding to this provider.
140    ///
141    /// # Errors
142    ///
143    /// Returns an error as a String if there was a problem accessing the Key Info Manager.
144    fn get_all(&self, provider_identity: ProviderIdentity) -> Result<Vec<KeyIdentity>, String>;
145
146    /// Inserts a new mapping between the KeyIdentity and the key info. If the KeyIdentity already exists,
147    /// overwrite the existing mapping and returns the old `KeyInfo`. Otherwise returns `None`.
148    ///
149    /// # Errors
150    ///
151    /// Returns an error as a String if there was a problem accessing the Key Info Manager.
152    fn insert(
153        &mut self,
154        key_identity: KeyIdentity,
155        key_info: KeyInfo,
156    ) -> Result<Option<KeyInfo>, String>;
157
158    /// Removes a KeyIdentity mapping and returns it. Does nothing and returns `None` if the mapping
159    /// does not exist.
160    ///
161    /// # Errors
162    ///
163    /// Returns an error as a String if there was a problem accessing the Key Info Manager.
164    fn remove(&mut self, key_identity: &KeyIdentity) -> Result<Option<KeyInfo>, String>;
165
166    /// Check if a KeyIdentity mapping exists.
167    ///
168    /// # Errors
169    ///
170    /// Returns an error as a String if there was a problem accessing the Key Info Manager.
171    fn exists(&self, key_identity: &KeyIdentity) -> Result<bool, String>;
172}
173
174/// KeyInfoManager client structure that bridges between the KIM and the providers that need
175/// to use it.
176#[derive(Derivative)]
177#[derivative(Debug)]
178pub struct KeyInfoManagerClient {
179    provider_identity: ProviderIdentity,
180    #[derivative(Debug = "ignore")]
181    key_info_manager_impl: Arc<RwLock<dyn ManageKeyInfo + Send + Sync>>,
182}
183
184impl KeyInfoManagerClient {
185    /// Get the KeyIdentity representing a key.
186    pub fn get_key_identity(
187        &self,
188        application: ApplicationIdentity,
189        key_name: String,
190    ) -> KeyIdentity {
191        KeyIdentity::new(application, self.provider_identity.clone(), key_name)
192    }
193
194    /// Get the key ID for a given KeyIdentity
195    ///
196    /// The ID does not have to be a specific type. Rather, it must implement the `serde::Deserialize`
197    /// trait. Before returning, an instance of that type is created from the bytes stored by the KIM.
198    ///
199    /// # Errors
200    ///
201    /// If the key does not exist, PsaErrorDoesNotExist is returned.  If any error occurs while fetching
202    /// the key info, KeyInfoManagerError is returned. If deserializing the stored key ID to the desired
203    /// type fails, InvalidEncoding is returned.
204    pub fn get_key_id<T: DeserializeOwned>(
205        &self,
206        key_identity: &KeyIdentity,
207    ) -> parsec_interface::requests::Result<T> {
208        let key_info_manager_impl = self
209            .key_info_manager_impl
210            .read()
211            .expect("Key Info Manager lock poisoned");
212        let key_info = match key_info_manager_impl.get(key_identity) {
213            Ok(Some(key_info)) => key_info,
214            Ok(None) => return Err(ResponseStatus::PsaErrorDoesNotExist),
215            Err(string) => return Err(to_response_status(string)),
216        };
217        // The `deserialize` call below creates a new instance of T decoupled from the
218        // scope of the lock acquired above.
219        Ok(bincode::deserialize(&key_info.id)?)
220    }
221
222    /// Get the `Attributes` for a given KeyIdentity
223    ///
224    /// # Errors
225    ///
226    /// If the key does not exist, PsaErrorDoesNotExist is returned. If any other error occurs,
227    /// KeyInfoManagerError is returned.
228    pub fn get_key_attributes(
229        &self,
230        key_identity: &KeyIdentity,
231    ) -> parsec_interface::requests::Result<Attributes> {
232        let key_info_manager_impl = self
233            .key_info_manager_impl
234            .read()
235            .expect("Key Info Manager lock poisoned");
236        let key_info = match key_info_manager_impl.get(key_identity) {
237            Ok(Some(key_info)) => key_info,
238            Ok(None) => return Err(ResponseStatus::PsaErrorDoesNotExist),
239            Err(string) => return Err(to_response_status(string)),
240        };
241        Ok(key_info.attributes)
242    }
243
244    /// Get all the key identities for the current provider
245    pub fn get_all(&self) -> parsec_interface::requests::Result<Vec<KeyIdentity>> {
246        let key_info_manager_impl = self
247            .key_info_manager_impl
248            .read()
249            .expect("Key Info Manager lock poisoned");
250
251        key_info_manager_impl
252            .get_all(self.provider_identity.clone())
253            .map_err(to_response_status)
254    }
255
256    /// Remove the key represented by a KeyIdentity and return the stored info.
257    ///
258    /// # Errors
259    ///
260    /// If the key does not exist, PsaErrorDoesNotExist is returned. If any other error occurs,
261    /// KeyInfoManagerError is returned.
262    pub fn remove_key_info(
263        &self,
264        key_identity: &KeyIdentity,
265    ) -> parsec_interface::requests::Result<()> {
266        let mut key_info_manager_impl = self
267            .key_info_manager_impl
268            .write()
269            .expect("Key Info Manager lock poisoned");
270        match key_info_manager_impl.remove(key_identity) {
271            Ok(Some(_key_info)) => Ok(()),
272            Ok(None) => Err(ResponseStatus::PsaErrorDoesNotExist),
273            Err(string) => Err(to_response_status(string)),
274        }
275    }
276
277    /// Insert key info for a given KeyIdentity.
278    ///
279    /// # Errors
280    ///
281    /// If the KeyIdentity already existed in the KIM, PsaErrorAlreadyExists is returned. For
282    /// any other error occurring in the KIM, KeyInfoManagerError is returned.
283    pub fn insert_key_info<T: Serialize>(
284        &self,
285        key_identity: KeyIdentity,
286        key_id: &T,
287        attributes: Attributes,
288    ) -> parsec_interface::requests::Result<()> {
289        let mut key_info_manager_impl = self
290            .key_info_manager_impl
291            .write()
292            .expect("Key Info Manager lock poisoned");
293        let key_info = KeyInfo {
294            id: bincode::serialize(key_id)?,
295            attributes,
296        };
297
298        match key_info_manager_impl.insert(key_identity, key_info) {
299            Ok(None) => Ok(()),
300            Ok(Some(_)) => Err(ResponseStatus::PsaErrorAlreadyExists),
301            Err(string) => Err(to_response_status(string)),
302        }
303    }
304
305    /// Replace the KeyInfo saved for a given KeyIdentity
306    ///
307    /// # Errors
308    ///
309    /// If the key identity doesn't exist in the KIM, PsaErrorDoesNotExist is returned. For
310    /// any other error occurring in the KIM, KeyInfoManagerError is returned.
311    pub fn replace_key_info<T: Serialize>(
312        &self,
313        key_identity: KeyIdentity,
314        key_id: &T,
315        attributes: Attributes,
316    ) -> parsec_interface::requests::Result<()> {
317        let mut key_info_manager_impl = self
318            .key_info_manager_impl
319            .write()
320            .expect("Key Info Manager lock poisoned");
321        let key_info = KeyInfo {
322            id: bincode::serialize(key_id)?,
323            attributes,
324        };
325
326        match key_info_manager_impl.insert(key_identity.clone(), key_info) {
327            Ok(None) => {
328                let _ = key_info_manager_impl
329                    .remove(&key_identity)
330                    .map_err(to_response_status)?;
331                Err(ResponseStatus::PsaErrorDoesNotExist)
332            }
333            Ok(Some(_)) => Ok(()),
334            Err(string) => Err(to_response_status(string)),
335        }
336    }
337
338    /// Returns a Vec<ApplicationIdentity> of clients that have keys in this provider.
339    ///
340    /// # Errors
341    ///
342    /// Returns an error as a String if there was a problem accessing the Key Info Manager.
343    pub fn list_clients(&self) -> parsec_interface::requests::Result<Vec<ApplicationIdentity>> {
344        let key_info_manager_impl = self
345            .key_info_manager_impl
346            .read()
347            .expect("Key Info Manager lock poisoned");
348        let key_identities = key_info_manager_impl
349            .get_all(self.provider_identity.clone())
350            .map_err(to_response_status)?;
351
352        let mut clients = Vec::new();
353        for key_identity in key_identities {
354            if !clients.contains(&key_identity.application)
355                && !key_identity.application.is_internal()
356            {
357                clients.push(key_identity.application.clone());
358            }
359        }
360
361        Ok(clients)
362    }
363
364    /// Returns a Vec of the KeyInfo objects corresponding to the given ApplicationIdentity,
365    /// and the KIM client ProviderIdentity.
366    ///
367    /// # Errors
368    ///
369    /// Returns an error as a String if there was a problem accessing the Key Info Manager.
370    pub fn list_keys(
371        &self,
372        application_identity: &ApplicationIdentity,
373    ) -> parsec_interface::requests::Result<Vec<parsec_interface::operations::list_keys::KeyInfo>>
374    {
375        use parsec_interface::operations::list_keys::KeyInfo;
376        let key_info_manager_impl = self
377            .key_info_manager_impl
378            .read()
379            .expect("Key Info Manager lock poisoned");
380
381        let mut keys: Vec<KeyInfo> = Vec::new();
382        let mut key_identities = key_info_manager_impl
383            .get_all(self.provider_identity.clone())
384            .map_err(to_response_status)?;
385
386        key_identities.retain(|key_identity| !key_identity.application().is_internal());
387        for key_identity in key_identities {
388            // If the OnDisk KIM is being used, only check if the app name is the same.
389            // Otherwise, check if the entire ApplicationIdentity matches.
390            // If it does not match, skip to the next key.
391            match key_info_manager_impl.key_info_manager_type() {
392                KeyInfoManagerType::OnDisk => {
393                    if key_identity.application().name() != application_identity.name() {
394                        continue;
395                    }
396                }
397                _ => {
398                    if key_identity.application() != application_identity {
399                        continue;
400                    }
401                }
402            }
403
404            let key_info = key_info_manager_impl
405                .get(&key_identity)
406                .map_err(to_response_status)?;
407            let key_info = match key_info {
408                Some(key_info) => key_info,
409                _ => continue,
410            };
411
412            #[allow(deprecated)]
413            let key_triple =
414                KeyTriple::try_from(key_identity.clone()).map_err(to_response_status)?;
415
416            // The KeyInfo structure we return here may need changing in the future to
417            // accomodate for different authenticators, provider names etc.
418            #[allow(deprecated)]
419            keys.push(KeyInfo {
420                provider_id: *key_triple.provider_id(),
421                name: key_identity.key_name().to_string(),
422                attributes: key_info.attributes,
423            });
424        }
425
426        Ok(keys)
427    }
428
429    /// Check if a KeyIdentity exists in the Key Info Manager and return a ResponseStatus
430    ///
431    /// # Errors
432    ///
433    /// Returns PsaErrorAlreadyExists if the KeyIdentity already exists or KeyInfoManagerError for
434    /// another error.
435    pub fn does_not_exist(&self, key_identity: &KeyIdentity) -> Result<(), ResponseStatus> {
436        let key_info_manager_impl = self
437            .key_info_manager_impl
438            .read()
439            .expect("Key Info Manager lock poisoned");
440
441        if key_info_manager_impl
442            .exists(key_identity)
443            .map_err(to_response_status)?
444        {
445            Err(ResponseStatus::PsaErrorAlreadyExists)
446        } else {
447            Ok(())
448        }
449    }
450}
451
452/// Builder for KeyInfoManager clients
453#[derive(Derivative)]
454#[derivative(Debug)]
455pub struct KeyInfoManagerFactory {
456    #[derivative(Debug = "ignore")]
457    key_info_manager_impl: Arc<RwLock<dyn ManageKeyInfo + Send + Sync>>,
458}
459
460impl KeyInfoManagerFactory {
461    /// Create a KeyInfoManagerFactory
462    pub fn new(config: &KeyInfoManagerConfig, default_auth_type: AuthType) -> Result<Self> {
463        let factory = match config.manager_type {
464            KeyInfoManagerType::OnDisk => {
465                let mut builder = on_disk_manager::OnDiskKeyInfoManagerBuilder::new();
466                if let Some(store_path) = &config.store_path {
467                    builder = builder.with_mappings_dir_path(store_path.into());
468                }
469                builder = builder.with_auth_type(default_auth_type);
470                let manager = builder.build()?;
471                KeyInfoManagerFactory {
472                    key_info_manager_impl: Arc::new(RwLock::new(manager)),
473                }
474            }
475            KeyInfoManagerType::SQLite => {
476                let mut builder = sqlite_manager::SQLiteKeyInfoManagerBuilder::new();
477                if let Some(sqlite_db_path) = &config.sqlite_db_path {
478                    builder = builder.with_db_path(sqlite_db_path.into());
479                }
480                let manager = builder.build()?;
481                KeyInfoManagerFactory {
482                    key_info_manager_impl: Arc::new(RwLock::new(manager)),
483                }
484            }
485        };
486
487        Ok(factory)
488    }
489
490    /// Build a KeyInfoManagerClient
491    pub fn build_client(&self, provider_identity: ProviderIdentity) -> KeyInfoManagerClient {
492        KeyInfoManagerClient {
493            key_info_manager_impl: self.key_info_manager_impl.clone(),
494            provider_identity,
495        }
496    }
497}