1use crate::authenticators::{Application, ApplicationIdentity, Auth, INTERNAL_APP_NAME};
16use crate::utils::config::KeyInfoManagerType;
17
18use super::{KeyIdentity, KeyInfo, ManageKeyInfo, ProviderIdentity};
19use crate::providers::core::Provider as CoreProvider;
20#[cfg(feature = "cryptoauthlib-provider")]
21use crate::providers::cryptoauthlib::Provider as CryptoAuthLibProvider;
22#[cfg(feature = "mbed-crypto-provider")]
23use crate::providers::mbed_crypto::Provider as MbedCryptoProvider;
24#[cfg(feature = "pkcs11-provider")]
25use crate::providers::pkcs11::Provider as Pkcs11Provider;
26#[cfg(feature = "tpm-provider")]
27use crate::providers::tpm::Provider as TpmProvider;
28#[cfg(feature = "trusted-service-provider")]
29use crate::providers::trusted_service::Provider as TrustedServiceProvider;
30use anyhow::{Context, Result};
31use base64::Engine;
32use log::{error, info, warn};
33use parsec_interface::requests::{AuthType, ProviderId};
34use std::collections::HashMap;
35use std::convert::TryFrom;
36use std::ffi::OsStr;
37use std::fs::Permissions;
38use std::fs::{DirEntry, File};
39use std::io::{Error, ErrorKind, Read, Write};
40use std::ops::Deref;
41use std::os::unix::fs::PermissionsExt;
42use std::path::{Path, PathBuf};
43use std::{fmt, fs};
44
45pub const DEFAULT_MAPPINGS_PATH: &str = "/var/lib/parsec/mappings";
47
48const INTERNAL_KEYS_PARSEC_DIR: &str = INTERNAL_APP_NAME;
50
51pub const DIR_PERMISSION: u32 = 0o700;
54
55pub const FILE_PERMISSION: u32 = 0o600;
58
59const CORE_PROVIDER: &str = "core";
60const PKCS11_PROVIDER: &str = "pkcs11";
61const MBEDCRYPTO_PROVIDER: &str = "mbedcrypto";
62const TPM_PROVIDER: &str = "tpm";
63const TRUSTEDS_PROVIDER: &str = "trusted-service";
64const CRYPTOAUTH_PROVIDER: &str = "cryptoauthlib";
65
66const PROVIDER_NAMES: [&str; 6] = [
68 CORE_PROVIDER,
69 PKCS11_PROVIDER,
70 MBEDCRYPTO_PROVIDER,
71 TPM_PROVIDER,
72 TRUSTEDS_PROVIDER,
73 CRYPTOAUTH_PROVIDER,
74];
75
76#[deprecated(since = "0.9.0", note = "ApplicationIdentity should be used instead.")]
78#[derive(Debug, Clone, Eq, PartialEq, Hash)]
79pub struct ApplicationName {
80 name: String,
81}
82
83#[allow(deprecated)]
84impl Deref for ApplicationName {
85 type Target = String;
86
87 fn deref(&self) -> &Self::Target {
88 &self.name
89 }
90}
91
92#[allow(deprecated)]
93#[deprecated(since = "0.9.0", note = "ApplicationIdentity should be used instead.")]
94impl ApplicationName {
95 pub fn from_name(name: String) -> ApplicationName {
97 ApplicationName { name }
98 }
99}
100
101#[allow(deprecated)]
102impl fmt::Display for ApplicationName {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 write!(f, "{}", self.name)
105 }
106}
107
108#[allow(deprecated)]
109impl From<Application> for ApplicationName {
110 fn from(app: Application) -> Self {
111 ApplicationName::from_name(app.identity().name().clone())
112 }
113}
114
115#[deprecated(since = "0.9.0", note = "KeyIdentity should be used instead.")]
120#[allow(deprecated)]
121#[derive(Debug, Clone, PartialEq, Eq, Hash)]
122pub struct KeyTriple {
123 app_name: ApplicationName,
124 provider_id: ProviderId,
125 key_name: String,
126}
127
128#[allow(deprecated)]
129#[deprecated(since = "0.9.0", note = "KeyIdentity should be used instead.")]
130impl KeyTriple {
131 pub fn new(app_name: ApplicationName, provider_id: ProviderId, key_name: String) -> KeyTriple {
133 KeyTriple {
134 app_name,
135 provider_id,
136 key_name,
137 }
138 }
139
140 pub fn belongs_to_provider(&self, provider_id: ProviderId) -> bool {
142 self.provider_id == provider_id
143 }
144 pub fn provider_id(&self) -> &ProviderId {
146 &self.provider_id
147 }
148
149 pub fn key_name(&self) -> &str {
151 &self.key_name
152 }
153
154 pub fn app_name(&self) -> &ApplicationName {
156 &self.app_name
157 }
158}
159
160#[allow(deprecated)]
161impl fmt::Display for KeyTriple {
162 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163 write!(
164 f,
165 "KeyTriple: app_name=\"{}\" provider_id={} key_name=\"{}\"",
166 self.app_name, self.provider_id, self.key_name
167 )
168 }
169}
170
171#[allow(deprecated)]
172impl TryFrom<KeyIdentity> for KeyTriple {
173 type Error = String;
174
175 fn try_from(key_identity: KeyIdentity) -> std::result::Result<Self, Self::Error> {
176 let provider_id = match key_identity.provider.uuid().as_str() {
177 CoreProvider::PROVIDER_UUID => Ok(ProviderId::Core),
178 #[cfg(feature = "cryptoauthlib-provider")]
179 CryptoAuthLibProvider::PROVIDER_UUID => Ok(ProviderId::CryptoAuthLib),
180 #[cfg(feature = "mbed-crypto-provider")]
181 MbedCryptoProvider::PROVIDER_UUID => Ok(ProviderId::MbedCrypto),
182 #[cfg(feature = "pkcs11-provider")]
183 Pkcs11Provider::PROVIDER_UUID => Ok(ProviderId::Pkcs11),
184 #[cfg(feature = "tpm-provider")]
185 TpmProvider::PROVIDER_UUID => Ok(ProviderId::Tpm),
186 #[cfg(feature = "trusted-service-provider")]
187 TrustedServiceProvider::PROVIDER_UUID => Ok(ProviderId::TrustedService),
188 _ => Err(format!(
189 "Cannot convert from KeyIdentity to KeyTriple.
190 Provider \"{}\" is not recognised.
191 Could be it does not exist, or Parsec was not compiled with the required provider feature flags.",
192 key_identity.provider().uuid()
193 )),
194 }?;
195
196 Ok(KeyTriple {
197 provider_id,
198 app_name: ApplicationName::from_name(key_identity.application().name().to_string()),
199 key_name: key_identity.key_name,
200 })
201 }
202}
203
204#[allow(deprecated)]
205impl TryFrom<(KeyTriple, ProviderIdentity, Auth)> for KeyIdentity {
206 type Error = String;
207
208 fn try_from(
209 (key_triple, provider_identity, auth): (KeyTriple, ProviderIdentity, Auth),
210 ) -> std::result::Result<Self, Self::Error> {
211 let provider_uuid = match key_triple.provider_id {
213 ProviderId::Core => Ok::<String, Self::Error>(
214 CoreProvider::PROVIDER_UUID.to_string(),
215 ),
216 #[cfg(feature = "cryptoauthlib-provider")]
217 ProviderId::CryptoAuthLib => Ok::<String, Self::Error>(CryptoAuthLibProvider::PROVIDER_UUID.to_string()),
218 #[cfg(feature = "mbed-crypto-provider")]
219 ProviderId::MbedCrypto => Ok::<String, Self::Error>(MbedCryptoProvider::PROVIDER_UUID.to_string()),
220 #[cfg(feature = "pkcs11-provider")]
221 ProviderId::Pkcs11 => Ok::<String, Self::Error>(Pkcs11Provider::PROVIDER_UUID.to_string()),
222 #[cfg(feature = "tpm-provider")]
223 ProviderId::Tpm => Ok::<String, Self::Error>(TpmProvider::PROVIDER_UUID.to_string()),
224 #[cfg(feature = "trusted-service-provider")]
225 ProviderId::TrustedService => Ok::<String, Self::Error>(TrustedServiceProvider::PROVIDER_UUID.to_string()),
226 #[cfg(not(all(
227 feature = "cryptoauthlib-provider",
228 feature = "mbed-crypto-provider",
229 feature = "pkcs11-provider",
230 feature = "tpm-provider",
231 feature = "trusted-service-provider",
232 )))]
233 _ => Err(format!("Cannot convert from KeyTriple to KeyIdentity.\nProvider \"{}\" is not recognised.\nCould be it does not exist, or Parsec was not compiled with the required provider feature flags.", key_triple.provider_id)),
234 }?;
235
236 let app_identity = match auth {
237 Auth::Internal => ApplicationIdentity::new_internal(),
238 Auth::Client(auth_type) => {
239 ApplicationIdentity::new(key_triple.app_name().to_string(), auth_type)
240 }
241 };
242 Ok(KeyIdentity {
243 provider: ProviderIdentity::new(provider_uuid, provider_identity.name().clone()),
244 application: app_identity,
245 key_name: key_triple.key_name,
246 })
247 }
248}
249
250#[derive(Debug)]
252pub struct OnDiskKeyInfoManager {
253 #[allow(deprecated)]
255 key_store: HashMap<KeyTriple, KeyInfo>,
256 #[allow(deprecated)]
258 key_store_internal: HashMap<KeyTriple, KeyInfo>,
259 mappings_dir_path: PathBuf,
262 auth_type: AuthType,
264}
265
266#[allow(deprecated)]
270fn key_triple_to_base64_filenames(key_triple: &KeyTriple) -> (String, String, String) {
271 (
272 base64::engine::general_purpose::URL_SAFE.encode(key_triple.app_name.as_bytes()),
273 (key_triple.provider_id as u8).to_string(),
274 base64::engine::general_purpose::URL_SAFE.encode(key_triple.key_name.as_bytes()),
275 )
276}
277
278fn base64_data_to_string(base64_bytes: &[u8]) -> Result<String, String> {
284 match base64::engine::general_purpose::URL_SAFE.decode(base64_bytes) {
285 Ok(decode_bytes) => match String::from_utf8(decode_bytes) {
286 Ok(string) => Ok(string),
287 Err(error) => Err(error.to_string()),
288 },
289 Err(error) => Err(error.to_string()),
290 }
291}
292
293#[allow(deprecated)]
300fn base64_data_triple_to_key_triple(
301 app_name: &[u8],
302 provider_id: ProviderId,
303 key_name: &[u8],
304) -> Result<KeyTriple, String> {
305 let app_name = ApplicationName::from_name(base64_data_to_string(app_name)?);
306 let key_name = base64_data_to_string(key_name)?;
307
308 Ok(KeyTriple {
309 app_name,
310 provider_id,
311 key_name,
312 })
313}
314
315fn os_str_to_u8_ref(os_str: &OsStr) -> std::io::Result<&[u8]> {
321 match os_str.to_str() {
322 Some(str) => Ok(str.as_bytes()),
323 None => Err(Error::new(
324 ErrorKind::Other,
325 "Conversion from PathBuf to String failed.",
326 )),
327 }
328}
329
330fn os_str_to_provider_id(os_str: &OsStr) -> std::io::Result<ProviderId> {
336 match os_str.to_str() {
337 Some(str) => match str.parse::<u8>() {
338 Ok(provider_id_u8) => match ProviderId::try_from(provider_id_u8) {
339 Ok(provider_id) => Ok(provider_id),
340 Err(response_status) => {
341 Err(Error::new(ErrorKind::Other, response_status.to_string()))
342 }
343 },
344 Err(_) => Err(Error::new(
345 ErrorKind::Other,
346 "Failed to convert Provider directory name to an u8 number.",
347 )),
348 },
349 None => Err(Error::new(
350 ErrorKind::Other,
351 "Conversion from PathBuf to String failed.",
352 )),
353 }
354}
355
356fn split_provider_key_filename(filename: &str) -> Option<(String, String)> {
362 for name in PROVIDER_NAMES {
363 if filename.starts_with(name) {
364 return Some((name.to_string(), filename.replacen(name, "", 1)));
365 }
366 }
367 None
368}
369
370fn provider_id_to_str(provid: ProviderId) -> &'static str {
371 match provid {
372 ProviderId::Core => CORE_PROVIDER,
373 ProviderId::Pkcs11 => PKCS11_PROVIDER,
374 ProviderId::MbedCrypto => MBEDCRYPTO_PROVIDER,
375 ProviderId::Tpm => TPM_PROVIDER,
376 ProviderId::TrustedService => TRUSTEDS_PROVIDER,
377 ProviderId::CryptoAuthLib => CRYPTOAUTH_PROVIDER,
378 }
379}
380
381fn str_to_provider_id(provid: &str) -> Option<ProviderId> {
382 match provid {
383 CORE_PROVIDER => Some(ProviderId::Core),
384 PKCS11_PROVIDER => Some(ProviderId::Pkcs11),
385 MBEDCRYPTO_PROVIDER => Some(ProviderId::MbedCrypto),
386 TPM_PROVIDER => Some(ProviderId::Tpm),
387 TRUSTEDS_PROVIDER => Some(ProviderId::TrustedService),
388 CRYPTOAUTH_PROVIDER => Some(ProviderId::CryptoAuthLib),
389 _ => None,
390 }
391}
392
393fn prov_and_key_to_str(provider_id: ProviderId, key_name: &str) -> String {
394 let mut p_name = provider_id_to_str(provider_id).to_string();
395 p_name.push_str(key_name);
396 p_name
397}
398
399fn list_dirs(path: &Path) -> std::io::Result<Vec<PathBuf>> {
401 let dir_entries: std::io::Result<Vec<DirEntry>> = path.read_dir()?.collect();
404 Ok(dir_entries?
405 .iter()
406 .map(|dir_entry| dir_entry.path())
407 .filter(|dir_path| dir_path.is_dir())
408 .collect())
409}
410
411fn list_files(path: &Path) -> std::io::Result<Vec<PathBuf>> {
413 let dir_entries: std::io::Result<Vec<DirEntry>> = path.read_dir()?.collect();
414 Ok(dir_entries?
415 .iter()
416 .map(|dir_entry| dir_entry.path())
417 .filter(|dir_path| dir_path.is_file())
418 .collect())
419}
420
421#[allow(deprecated)]
426impl OnDiskKeyInfoManager {
427 fn new(mappings_dir_path: PathBuf, auth_type: AuthType) -> Result<OnDiskKeyInfoManager> {
462 let mut key_store = HashMap::new();
463 let mut key_store_internal = HashMap::new();
464
465 fs::create_dir_all(&mappings_dir_path).with_context(|| {
467 format!(
468 "Failed to create Key Info Mappings directory at {:?}",
469 mappings_dir_path
470 )
471 })?;
472
473 let parsec_dir = mappings_dir_path.join(INTERNAL_KEYS_PARSEC_DIR);
476 fs::create_dir_all(&parsec_dir)
477 .with_context(|| format!("Failed to create Parsec directory at {:?}", parsec_dir))?;
478 fs::set_permissions(&parsec_dir, Permissions::from_mode(DIR_PERMISSION))?;
479
480 for internal_key_path in list_files(&parsec_dir)?.iter() {
481 let key_name_internal = base64_data_to_string(os_str_to_u8_ref(
482 internal_key_path
483 .file_name()
484 .expect("The key name directory path should contain a final component."),
485 )?)
486 .map_err(|e| Error::new(ErrorKind::Other, e))?;
487
488 let keytriple = match split_provider_key_filename(&key_name_internal) {
490 None => continue,
491 Some((prov, key_name)) => KeyTriple::new(
492 ApplicationName::from_name(INTERNAL_KEYS_PARSEC_DIR.to_string()),
493 str_to_provider_id(&prov).unwrap(),
496 key_name,
497 ),
498 };
499
500 let mut key_info = Vec::new();
501 let mut key_info_file = File::open(internal_key_path).with_context(|| {
502 format!(
503 "Failed to open Key Info Mappings file at {:?}",
504 internal_key_path
505 )
506 })?;
507 let _ = key_info_file.read_to_end(&mut key_info)?;
508 let key_info = bincode::deserialize(&key_info[..]).map_err(|e| {
509 format_error!("Error deserializing key info", e);
510 Error::new(ErrorKind::Other, "error deserializing key info")
511 })?;
512 let _ = key_store_internal.insert(keytriple, key_info);
513 }
514
515 for app_name_dir_path in list_dirs(&mappings_dir_path)?.iter() {
516 for provider_dir_path in list_dirs(app_name_dir_path)?.iter() {
517 for key_name_file_path in list_files(provider_dir_path)?.iter() {
518 let mut key_info = Vec::new();
519 let mut key_info_file = File::open(key_name_file_path).with_context(|| {
520 format!(
521 "Failed to open Key Info Mappings file at {:?}",
522 key_name_file_path
523 )
524 })?;
525 let _ = key_info_file.read_to_end(&mut key_info)?;
526 let key_info = bincode::deserialize(&key_info[..]).map_err(|e| {
527 format_error!("Error deserializing key info", e);
528 Error::new(ErrorKind::Other, "error deserializing key info")
529 })?;
530 match base64_data_triple_to_key_triple(
531 os_str_to_u8_ref(app_name_dir_path.file_name().expect(
532 "The application name directory path should contain a final component.",
533 ))?,
534 os_str_to_provider_id(provider_dir_path.file_name().expect(
535 "The provider directory path should contain a final component.",
536 ))?,
537 os_str_to_u8_ref(key_name_file_path.file_name().expect(
538 "The key name directory path should contain a final component.",
539 ))?,
540 ) {
541 Ok(key_triple) => {
542 if crate::utils::GlobalConfig::log_error_details() {
543 warn!(
544 "Inserting Key Triple ({}) mapping read from disk.",
545 key_triple.clone()
546 );
547 }
548 let _ = key_store.insert(key_triple, key_info);
549 }
550 Err(string) => {
551 format_error!(
552 "Failed to convert the mapping path found to an UTF-8 string",
553 string
554 );
555 return Err(
556 Error::new(ErrorKind::Other, "error parsing mapping path").into()
557 );
558 }
559 }
560 }
561 }
562 }
563
564 if !crate::utils::GlobalConfig::log_error_details() {
565 info!("Found {} mapping files", key_store.len());
566 }
567
568 let permissions = Permissions::from_mode(DIR_PERMISSION);
569 fs::set_permissions(&mappings_dir_path, permissions)?;
570
571 Ok(OnDiskKeyInfoManager {
572 key_store,
573 key_store_internal,
574 mappings_dir_path,
575 auth_type,
576 })
577 }
578
579 fn save_mapping(
583 &self,
584 key_triple: &KeyTriple,
585 key_info: &KeyInfo,
586 auth: &Auth,
587 ) -> std::io::Result<()> {
588 if crate::utils::GlobalConfig::log_error_details() {
589 warn!(
590 "Saving Key Triple ({}) mapping to disk.",
591 key_triple.clone()
592 );
593 }
594 let (app_name, prov, key_name) = key_triple_to_base64_filenames(key_triple);
595 let key_name_file_path = match auth {
596 Auth::Internal => {
597 let prov_key_name =
598 prov_and_key_to_str(key_triple.provider_id, &key_triple.key_name);
599 let prov_key_name =
600 base64::engine::general_purpose::URL_SAFE.encode(prov_key_name.as_bytes());
601 self.mappings_dir_path
603 .join(INTERNAL_KEYS_PARSEC_DIR)
604 .join(prov_key_name)
605 }
606 Auth::Client(_) => {
607 let app_dir_path = self.mappings_dir_path.join(app_name);
609 let provider_dir_path = app_dir_path.join(prov);
610 let key_name_file_path = provider_dir_path.join(key_name);
611 fs::create_dir_all(&provider_dir_path).map_err(|e| {
613 format_error!(
614 format!(
615 "Failed to create provider directory as {:?}",
616 &provider_dir_path
617 ),
618 e
619 );
620 e
621 })?;
622 let dir_permissions = Permissions::from_mode(DIR_PERMISSION);
623 fs::set_permissions(&app_dir_path, dir_permissions.clone())?;
624 fs::set_permissions(&provider_dir_path, dir_permissions)?;
625
626 if key_name_file_path.exists() {
627 fs::remove_file(&key_name_file_path)?;
628 }
629 key_name_file_path
630 }
631 };
632
633 let mut mapping_file = File::create(&key_name_file_path).map_err(|e| {
635 error!(
636 "Failed to create Key Info Mapping file at {:?}",
637 key_name_file_path
638 );
639 e
640 })?;
641
642 let file_permissions = Permissions::from_mode(FILE_PERMISSION);
643 fs::set_permissions(&key_name_file_path, file_permissions)?;
644 mapping_file.write_all(&bincode::serialize(key_info).map_err(|e| {
645 format_error!("Error serializing key info", e);
646 Error::new(ErrorKind::Other, "error serializing key info")
647 })?)
648 }
649
650 fn delete_mapping(&self, key_triple: &KeyTriple, auth: &Auth) -> std::io::Result<()> {
653 let (app_name, prov, key_name) = key_triple_to_base64_filenames(key_triple);
654 let key_name_file_path = match auth {
655 Auth::Internal => {
656 let prov_key_name = prov_and_key_to_str(key_triple.provider_id, &key_name);
657
658 self.mappings_dir_path
660 .join(INTERNAL_KEYS_PARSEC_DIR)
661 .join(prov_key_name)
662 }
663 Auth::Client(_) => self
664 .mappings_dir_path
665 .join(app_name)
666 .join(prov)
667 .join(key_name),
668 };
669 if key_name_file_path.exists() {
670 fs::remove_file(key_name_file_path)
671 } else {
672 Ok(())
673 }
674 }
675}
676
677#[allow(deprecated)]
678impl ManageKeyInfo for OnDiskKeyInfoManager {
679 fn key_info_manager_type(&self) -> KeyInfoManagerType {
680 KeyInfoManagerType::OnDisk
681 }
682
683 fn get(&self, key_identity: &KeyIdentity) -> Result<Option<&KeyInfo>, String> {
684 let key_triple = KeyTriple::try_from(key_identity.clone())?;
685 let curr_key_store = match key_identity.application().auth() {
688 &Auth::Internal => &self.key_store_internal,
689 _ => &self.key_store,
690 };
691
692 if let Some(key_info) = curr_key_store.get(&key_triple) {
693 Ok(Some(key_info))
694 } else {
695 Ok(None)
696 }
697 }
698
699 fn get_all(&self, provider_identity: ProviderIdentity) -> Result<Vec<KeyIdentity>, String> {
700 let provider_id = ProviderId::try_from(provider_identity.clone())?;
701 let mut key_identites = Vec::new();
702
703 let key_triples_internal = self
704 .key_store_internal
705 .keys()
706 .filter(|key_triple| key_triple.belongs_to_provider(provider_id));
707
708 for key_triple_internal in key_triples_internal {
709 let key_identity = KeyIdentity::try_from((
710 key_triple_internal.clone(),
711 provider_identity.clone(),
712 Auth::Internal,
713 ))?;
714 key_identites.push(key_identity)
715 }
716 let key_triples_external = self
717 .key_store
718 .keys()
719 .filter(|key_triple| key_triple.belongs_to_provider(provider_id));
720
721 for key_triple_external in key_triples_external {
722 let key_identity = KeyIdentity::try_from((
723 key_triple_external.clone(),
724 provider_identity.clone(),
725 Auth::Client(self.auth_type),
726 ))?;
727 key_identites.push(key_identity)
728 }
729 Ok(key_identites)
730 }
731
732 fn insert(
733 &mut self,
734 key_identity: KeyIdentity,
735 key_info: KeyInfo,
736 ) -> Result<Option<KeyInfo>, String> {
737 let key_triple = KeyTriple::try_from(key_identity.clone())?;
738 if let Err(err) =
739 self.save_mapping(&key_triple, &key_info, key_identity.application().auth())
740 {
741 Err(err.to_string())
742 } else if key_identity.application().is_internal() {
743 Ok(self.key_store_internal.insert(key_triple, key_info))
744 } else {
745 Ok(self.key_store.insert(key_triple, key_info))
746 }
747 }
748
749 fn remove(&mut self, key_identity: &KeyIdentity) -> Result<Option<KeyInfo>, String> {
750 let key_triple = KeyTriple::try_from(key_identity.clone())?;
751 if let Err(err) = self.delete_mapping(&key_triple, key_identity.application().auth()) {
752 return Err(err.to_string());
753 }
754 if key_identity.application().is_internal() {
755 Ok(self.key_store_internal.remove(&key_triple))
756 } else if !key_identity.application().is_internal() {
757 Ok(self.key_store.remove(&key_triple))
758 } else {
759 Ok(None)
760 }
761 }
762
763 fn exists(&self, key_identity: &KeyIdentity) -> Result<bool, String> {
764 let key_triple = KeyTriple::try_from(key_identity.clone())?;
765 match *key_identity.application().auth() {
766 Auth::Internal => Ok(self.key_store_internal.contains_key(&key_triple)),
767 Auth::Client(_) => Ok(self.key_store.contains_key(&key_triple)),
768 }
769 }
770}
771
772#[derive(Debug, Default)]
774pub struct OnDiskKeyInfoManagerBuilder {
775 mappings_dir_path: Option<PathBuf>,
776 auth_type: Option<AuthType>,
777}
778
779impl OnDiskKeyInfoManagerBuilder {
780 pub fn new() -> OnDiskKeyInfoManagerBuilder {
782 OnDiskKeyInfoManagerBuilder {
783 mappings_dir_path: None,
784 auth_type: None,
785 }
786 }
787
788 pub fn with_mappings_dir_path(mut self, path: PathBuf) -> OnDiskKeyInfoManagerBuilder {
790 self.mappings_dir_path = Some(path);
791
792 self
793 }
794
795 pub fn with_auth_type(mut self, default_auth_type: AuthType) -> OnDiskKeyInfoManagerBuilder {
797 self.auth_type = Some(default_auth_type);
798
799 self
800 }
801
802 pub fn build(self) -> Result<OnDiskKeyInfoManager> {
804 OnDiskKeyInfoManager::new(
805 self.mappings_dir_path
806 .unwrap_or_else(|| PathBuf::from(DEFAULT_MAPPINGS_PATH)),
807 self.auth_type.ok_or_else(|| {
808 Error::new(
809 ErrorKind::InvalidData,
810 "AuthType must be supplied to OnDiskKeyInfoManager",
811 )
812 })?,
813 )
814 }
815}
816
817#[cfg(test)]
818mod test {
819 use super::super::{KeyIdentity, KeyInfo, ManageKeyInfo};
820 use super::OnDiskKeyInfoManager;
821 use crate::key_info_managers::{ApplicationIdentity, ProviderIdentity};
822 use crate::providers::core::Provider as CoreProvider;
823 #[cfg(feature = "mbed-crypto-provider")]
824 use crate::providers::mbed_crypto::Provider as MbedCryptoProvider;
825 use parsec_interface::operations::psa_algorithm::{
826 Algorithm, AsymmetricSignature, Hash, SignHash,
827 };
828 use parsec_interface::operations::psa_key_attributes::{
829 Attributes, Lifetime, Policy, Type, UsageFlags,
830 };
831 use parsec_interface::requests::AuthType;
832 use std::fs;
833 use std::path::PathBuf;
834
835 fn test_key_attributes() -> Attributes {
836 Attributes {
837 lifetime: Lifetime::Persistent,
838 key_type: Type::Derive,
839 bits: 1024,
840 policy: Policy {
841 usage_flags: {
842 let mut usage_flags = UsageFlags::default();
843 let _ = usage_flags.set_sign_hash();
844 usage_flags
845 },
846 permitted_algorithms: Algorithm::AsymmetricSignature(
847 AsymmetricSignature::RsaPkcs1v15Sign {
848 hash_alg: SignHash::Specific(Hash::Sha256),
849 },
850 ),
851 },
852 }
853 }
854
855 fn test_key_info() -> KeyInfo {
856 KeyInfo {
857 id: vec![0x11, 0x22, 0x33],
858 attributes: test_key_attributes(),
859 }
860 }
861
862 #[test]
863 fn insert_get_key_info() {
864 let path = PathBuf::from(env!("OUT_DIR").to_owned() + "/insert_get_key_info_mappings");
865 let mut manager = OnDiskKeyInfoManager::new(path.clone(), AuthType::NoAuth).unwrap();
866
867 let key_identity = new_key_identity("insert_get_key_info".to_string());
868 let key_info = test_key_info();
869
870 assert!(manager.get(&key_identity).unwrap().is_none());
871
872 assert!(manager
873 .insert(key_identity.clone(), key_info.clone())
874 .unwrap()
875 .is_none());
876
877 let stored_key_info = manager
878 .get(&key_identity)
879 .unwrap()
880 .expect("Failed to get key info")
881 .clone();
882
883 assert_eq!(stored_key_info, key_info);
884 assert!(manager.remove(&key_identity).unwrap().is_some());
885 fs::remove_dir_all(path).unwrap();
886 }
887
888 #[test]
889 fn insert_remove_key() {
890 let path = PathBuf::from(env!("OUT_DIR").to_owned() + "/insert_remove_key_mappings");
891 let mut manager = OnDiskKeyInfoManager::new(path.clone(), AuthType::NoAuth).unwrap();
892
893 let key_identity = new_key_identity("insert_remove_key".to_string());
894 let key_info = test_key_info();
895
896 let _ = manager.insert(key_identity.clone(), key_info).unwrap();
897
898 assert!(manager.remove(&key_identity).unwrap().is_some());
899 fs::remove_dir_all(path).unwrap();
900 }
901
902 #[test]
903 fn remove_unexisting_key() {
904 let path = PathBuf::from(env!("OUT_DIR").to_owned() + "/remove_unexisting_key_mappings");
905 let mut manager = OnDiskKeyInfoManager::new(path.clone(), AuthType::NoAuth).unwrap();
906
907 let key_identity = new_key_identity("remove_unexisting_key".to_string());
908 assert_eq!(manager.remove(&key_identity).unwrap(), None);
909 fs::remove_dir_all(path).unwrap();
910 }
911
912 #[test]
913 fn exists() {
914 let path = PathBuf::from(env!("OUT_DIR").to_owned() + "/exists_mappings");
915 let mut manager = OnDiskKeyInfoManager::new(path.clone(), AuthType::NoAuth).unwrap();
916
917 let key_identity = new_key_identity("exists".to_string());
918 let key_info = test_key_info();
919
920 assert!(!manager.exists(&key_identity).unwrap());
921
922 let _ = manager.insert(key_identity.clone(), key_info).unwrap();
923 assert!(manager.exists(&key_identity).unwrap());
924
925 let _ = manager.remove(&key_identity).unwrap();
926 assert!(!manager.exists(&key_identity).unwrap());
927 fs::remove_dir_all(path).unwrap();
928 }
929
930 #[test]
931 fn insert_overwrites() {
932 let path = PathBuf::from(env!("OUT_DIR").to_owned() + "/insert_overwrites_mappings");
933 let mut manager = OnDiskKeyInfoManager::new(path.clone(), AuthType::NoAuth).unwrap();
934
935 let key_identity = new_key_identity("insert_overwrites".to_string());
936 let key_info_1 = test_key_info();
937 let key_info_2 = KeyInfo {
938 id: vec![0xaa, 0xbb, 0xcc],
939 attributes: test_key_attributes(),
940 };
941
942 let _ = manager.insert(key_identity.clone(), key_info_1).unwrap();
943 let _ = manager
944 .insert(key_identity.clone(), key_info_2.clone())
945 .unwrap();
946
947 let stored_key_info = manager
948 .get(&key_identity)
949 .unwrap()
950 .expect("Failed to get key info")
951 .clone();
952
953 assert_eq!(stored_key_info, key_info_2);
954 assert!(manager.remove(&key_identity).unwrap().is_some());
955 fs::remove_dir_all(path).unwrap();
956 }
957
958 #[test]
959 fn big_names_ascii() {
960 let path = PathBuf::from(env!("OUT_DIR").to_owned() + "/big_names_ascii_mappings");
961 let mut manager = OnDiskKeyInfoManager::new(path.clone(), AuthType::NoAuth).unwrap();
962
963 let big_app_name_ascii = " Lorem ipsum dolor sit amet, ei suas viris sea, deleniti repudiare te qui. Natum paulo decore ut nec, ne propriae offendit adipisci has. Eius clita legere mel at, ei vis minimum tincidunt.".to_string();
964 let big_key_name_ascii = " Lorem ipsum dolor sit amet, ei suas viris sea, deleniti repudiare te qui. Natum paulo decore ut nec, ne propriae offendit adipisci has. Eius clita legere mel at, ei vis minimum tincidunt.".to_string();
965
966 let key_identity = KeyIdentity::new(
967 ApplicationIdentity::new(big_app_name_ascii, AuthType::NoAuth),
968 ProviderIdentity::new(
969 CoreProvider::PROVIDER_UUID.to_string(),
970 CoreProvider::DEFAULT_PROVIDER_NAME.to_string(),
971 ),
972 big_key_name_ascii,
973 );
974 let key_info = test_key_info();
975
976 let _ = manager
977 .insert(key_identity.clone(), key_info.clone())
978 .unwrap();
979 assert_eq!(manager.remove(&key_identity).unwrap().unwrap(), key_info);
980 fs::remove_dir_all(path).unwrap();
981 }
982
983 #[test]
984 fn big_names_emoticons() {
985 let path = PathBuf::from(env!("OUT_DIR").to_owned() + "/big_names_emoticons_mappings");
986 let mut manager = OnDiskKeyInfoManager::new(path.clone(), AuthType::NoAuth).unwrap();
987
988 let big_app_name_emoticons = "😀😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐😑😒😓😔😕😖😗😘😙😚😛😜😝😞😟😠😡😢😣😤😥😦😧😨😩😪😫😬😭😮".to_string();
989 let big_key_name_emoticons = "😀😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐😑😒😓😔😕😖😗😘😙😚😛😜😝😞😟😠😡😢😣😤😥😦😧😨😩😪😫😬😭😮".to_string();
990
991 let key_identity = KeyIdentity::new(
992 ApplicationIdentity::new(big_app_name_emoticons, AuthType::NoAuth),
993 ProviderIdentity::new(
994 CoreProvider::PROVIDER_UUID.to_string(),
995 CoreProvider::DEFAULT_PROVIDER_NAME.to_string(),
996 ),
997 big_key_name_emoticons,
998 );
999 let key_info = test_key_info();
1000
1001 let _ = manager
1002 .insert(key_identity.clone(), key_info.clone())
1003 .unwrap();
1004 assert_eq!(manager.remove(&key_identity).unwrap().unwrap(), key_info);
1005 fs::remove_dir_all(path).unwrap();
1006 }
1007
1008 #[cfg(feature = "mbed-crypto-provider")]
1009 #[test]
1010 fn create_and_load() {
1011 let path = PathBuf::from(env!("OUT_DIR").to_owned() + "/create_and_load_mappings");
1012
1013 let app_name1 = "😀 Application One 😀".to_string();
1014 let key_name1 = "😀 Key One 😀".to_string();
1015 let key_identity_1 = KeyIdentity::new(
1016 ApplicationIdentity::new(app_name1, AuthType::NoAuth),
1017 ProviderIdentity::new(
1018 CoreProvider::PROVIDER_UUID.to_string(),
1019 CoreProvider::DEFAULT_PROVIDER_NAME.to_string(),
1020 ),
1021 key_name1,
1022 );
1023 let key_info1 = test_key_info();
1024
1025 let app_name2 = "😇 Application Two 😇".to_string();
1026 let key_name2 = "😇 Key Two 😇".to_string();
1027 let key_identity_2 = KeyIdentity::new(
1028 ApplicationIdentity::new(app_name2, AuthType::NoAuth),
1029 ProviderIdentity::new(
1030 MbedCryptoProvider::PROVIDER_UUID.to_string(),
1031 MbedCryptoProvider::DEFAULT_PROVIDER_NAME.to_string(),
1032 ),
1033 key_name2,
1034 );
1035 let key_info2 = KeyInfo {
1036 id: vec![0x12, 0x22, 0x32],
1037 attributes: test_key_attributes(),
1038 };
1039
1040 let app_name3 = "😈 Application Three 😈".to_string();
1041 let key_name3 = "😈 Key Three 😈".to_string();
1042 let key_identity_3 = KeyIdentity::new(
1043 ApplicationIdentity::new(app_name3, AuthType::NoAuth),
1044 ProviderIdentity::new(
1045 CoreProvider::PROVIDER_UUID.to_string(),
1046 CoreProvider::DEFAULT_PROVIDER_NAME.to_string(),
1047 ),
1048 key_name3,
1049 );
1050 let key_info3 = KeyInfo {
1051 id: vec![0x13, 0x23, 0x33],
1052 attributes: test_key_attributes(),
1053 };
1054 {
1055 let mut manager = OnDiskKeyInfoManager::new(path.clone(), AuthType::NoAuth).unwrap();
1056
1057 let _ = manager
1058 .insert(key_identity_1.clone(), key_info1.clone())
1059 .unwrap();
1060 let _ = manager
1061 .insert(key_identity_2.clone(), key_info2.clone())
1062 .unwrap();
1063 let _ = manager
1064 .insert(key_identity_3.clone(), key_info3.clone())
1065 .unwrap();
1066 }
1067 {
1069 let mut manager = OnDiskKeyInfoManager::new(path.clone(), AuthType::NoAuth).unwrap();
1070
1071 assert_eq!(manager.remove(&key_identity_1).unwrap().unwrap(), key_info1);
1072 assert_eq!(manager.remove(&key_identity_2).unwrap().unwrap(), key_info2);
1073 assert_eq!(manager.remove(&key_identity_3).unwrap().unwrap(), key_info3);
1074 }
1075
1076 fs::remove_dir_all(path).unwrap();
1077 }
1078
1079 #[cfg(feature = "mbed-crypto-provider")]
1080 #[test]
1081 fn create_and_load_internal_keys() {
1082 let path = PathBuf::from(env!("OUT_DIR").to_owned() + "/create_and_load_internal_mappings");
1083
1084 let key_name1 = "😀 Key One 😀".to_string();
1085 let key_identity_1 = KeyIdentity::new(
1086 ApplicationIdentity::new_internal(),
1087 ProviderIdentity::new(
1088 CoreProvider::PROVIDER_UUID.to_string(),
1089 CoreProvider::DEFAULT_PROVIDER_NAME.to_string(),
1090 ),
1091 key_name1,
1092 );
1093 let key_info1 = test_key_info();
1094 let key_name2 = "😇 Key Two 😇".to_string();
1095 let key_identity_2 = KeyIdentity::new(
1096 ApplicationIdentity::new_internal(),
1097 ProviderIdentity::new(
1098 MbedCryptoProvider::PROVIDER_UUID.to_string(),
1099 MbedCryptoProvider::DEFAULT_PROVIDER_NAME.to_string(),
1100 ),
1101 key_name2,
1102 );
1103 let key_info2 = KeyInfo {
1104 id: vec![0x12, 0x22, 0x32],
1105 attributes: test_key_attributes(),
1106 };
1107
1108 {
1109 let mut manager = OnDiskKeyInfoManager::new(path.clone(), AuthType::NoAuth).unwrap();
1110 let _ = manager
1111 .insert(key_identity_1.clone(), key_info1.clone())
1112 .unwrap();
1113 let _ = manager
1114 .insert(key_identity_2.clone(), key_info2.clone())
1115 .unwrap();
1116 }
1117 {
1119 let mut manager = OnDiskKeyInfoManager::new(path.clone(), AuthType::NoAuth).unwrap();
1120
1121 assert_eq!(
1122 manager
1123 .get_all(key_identity_1.provider.clone())
1124 .unwrap()
1125 .len(),
1126 1
1127 );
1128 assert_eq!(
1129 manager
1130 .get_all(key_identity_2.provider.clone())
1131 .unwrap()
1132 .len(),
1133 1
1134 );
1135
1136 assert_eq!(&key_info1, manager.get(&key_identity_1).unwrap().unwrap());
1138
1139 let mut key_identity3 = key_identity_2.clone();
1141 key_identity3.application = ApplicationIdentity::new(
1142 key_identity_2.application().name().to_string(),
1143 AuthType::UnixPeerCredentials,
1144 );
1145 assert_eq!(None, manager.get(&key_identity3).unwrap());
1146
1147 assert_eq!(manager.remove(&key_identity_1).unwrap().unwrap(), key_info1);
1148 assert_eq!(manager.remove(&key_identity_2).unwrap().unwrap(), key_info2);
1149 assert_eq!(
1150 manager
1151 .get_all(key_identity_1.provider.clone())
1152 .unwrap()
1153 .len(),
1154 0
1155 );
1156 }
1157
1158 fs::remove_dir_all(path).unwrap();
1159 }
1160
1161 fn new_key_identity(key_name: String) -> KeyIdentity {
1162 KeyIdentity::new(
1163 ApplicationIdentity::new("Testing Application 😎".to_string(), AuthType::NoAuth),
1164 ProviderIdentity::new(
1165 CoreProvider::PROVIDER_UUID.to_string(),
1166 CoreProvider::DEFAULT_PROVIDER_NAME.to_string(),
1167 ),
1168 key_name,
1169 )
1170 }
1171
1172 #[cfg(feature = "mbed-crypto-provider")]
1173 mod permissions_test {
1174 use super::*;
1175 use crate::key_info_managers::on_disk_manager::DIR_PERMISSION;
1176 use crate::key_info_managers::on_disk_manager::FILE_PERMISSION;
1177 use std::fs::Permissions;
1178 use std::io;
1179 use std::os::unix::fs::PermissionsExt;
1180 use std::path::Path;
1181
1182 fn check_permissions(dir: &Path) -> io::Result<()> {
1184 let file_permissions = Permissions::from_mode(FILE_PERMISSION);
1185 let dir_permissions = Permissions::from_mode(DIR_PERMISSION);
1186 if dir.is_dir() {
1187 for entry in fs::read_dir(dir)? {
1188 let path = entry?.path();
1189 if path.is_dir() {
1190 assert_eq!(
1191 fs::metadata(&path)?.permissions().mode() & dir_permissions.mode(),
1192 dir_permissions.mode()
1193 );
1194 check_permissions(&path)?;
1195 } else {
1196 assert_eq!(
1197 fs::metadata(&path)?.permissions().mode() & file_permissions.mode(),
1198 file_permissions.mode()
1199 );
1200 }
1201 }
1202 }
1203 Ok(())
1204 }
1205
1206 #[test]
1207 fn check_kim_permissions() {
1208 let dir_permissions = Permissions::from_mode(DIR_PERMISSION);
1209 let path = PathBuf::from(env!("OUT_DIR").to_owned() + "/check_permissions");
1210 let app_name1 = "App1".to_string();
1211 let key_name1 = "Key1".to_string();
1212 let key_identity_1 = KeyIdentity::new(
1213 ApplicationIdentity::new(app_name1, AuthType::NoAuth),
1214 ProviderIdentity::new(
1215 CoreProvider::PROVIDER_UUID.to_string(),
1216 CoreProvider::DEFAULT_PROVIDER_NAME.to_string(),
1217 ),
1218 key_name1,
1219 );
1220 let key_info1 = test_key_info();
1221
1222 let app_name2 = "App2".to_string();
1223 let key_name2 = "Key2".to_string();
1224 let key_identity_2 = KeyIdentity::new(
1225 ApplicationIdentity::new(app_name2, AuthType::NoAuth),
1226 ProviderIdentity::new(
1227 MbedCryptoProvider::PROVIDER_UUID.to_string(),
1228 MbedCryptoProvider::DEFAULT_PROVIDER_NAME.to_string(),
1229 ),
1230 key_name2,
1231 );
1232 let key_info2 = KeyInfo {
1233 id: vec![0x12, 0x22, 0x32],
1234 attributes: test_key_attributes(),
1235 };
1236
1237 let mut manager = OnDiskKeyInfoManager::new(path.clone(), AuthType::NoAuth).unwrap();
1238 assert_eq!(
1239 fs::metadata(path.clone()).unwrap().permissions().mode() & dir_permissions.mode(),
1240 dir_permissions.mode()
1241 );
1242 let _ = manager.insert(key_identity_1.clone(), key_info1).unwrap();
1243 let _ = manager.insert(key_identity_2.clone(), key_info2).unwrap();
1244
1245 let _ = check_permissions(&path).is_ok();
1246 let _ = manager.remove(&key_identity_1).unwrap().unwrap();
1247 let _ = manager.remove(&key_identity_2).unwrap().unwrap();
1248
1249 fs::remove_dir_all(path).unwrap();
1250 }
1251 }
1252}