From 8632fefce5d807defdfa94c70a12c6ecfe0043df Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Tue, 27 Jul 2021 11:23:58 +0100 Subject: [PATCH] Added provider names to the config. This is an optional field, and will default to a suitable name for each provider if it is not provided. Two providers cannot have the same name. Closes #487 Signed-off-by: Matt Davis --- config.toml | 46 +++++++++++++++++ src/providers/cryptoauthlib/mod.rs | 24 ++++++++- src/providers/mbed_crypto/mod.rs | 26 +++++++++- src/providers/pkcs11/mod.rs | 24 ++++++++- src/providers/tpm/mod.rs | 25 +++++++++- src/providers/trusted_service/mod.rs | 38 +++++++++++--- src/utils/config.rs | 74 ++++++++++++++++++++++++++++ src/utils/service_builder.rs | 30 +++++++---- 8 files changed, 266 insertions(+), 21 deletions(-) diff --git a/config.toml b/config.toml index e36a4e02..cda14b71 100644 --- a/config.toml +++ b/config.toml @@ -101,6 +101,16 @@ manager_type = "OnDisk" # Example of an Mbed Crypto provider configuration. [[provider]] +# ⚠ +# ⚠ WARNING: Provider name cannot change. +# ⚠ WARNING: Choose a suitable naming scheme for your providers now. +# ⚠ WARNING: Provider name defaults to "mbed-crypto-provider" if not provided, you will not be able to change +# ⚠ the provider's name from this if you decide to use the default. +# ⚠ WARNING: Changing provider name after use will lead to loss of existing keys. +# ⚠ +# (Optional) The name of the provider +name = "mbed-crypto-provider" + # (Required) Type of provider. provider_type = "MbedCrypto" @@ -114,6 +124,15 @@ key_info_manager = "on-disk-manager" # Example of a PKCS 11 provider configuration #[[provider]] +# ⚠ +# ⚠ WARNING: Provider name cannot change. +# ⚠ WARNING: Choose a suitable naming scheme for your providers now. +# ⚠ WARNING: Provider name defaults to "pkcs11-provider" if not provided, you will not be able to change +# ⚠ the provider's name from this if you decide to use the default. +# ⚠ WARNING: Changing provider name after use will lead to loss of existing keys. +# ⚠ +# (Optional) The name of the provider +# name = "pkcs11-provider" #provider_type = "Pkcs11" #key_info_manager = "on-disk-manager" # (Required for this provider) Path to the location of the dynamic library loaded by this provider. @@ -135,6 +154,15 @@ key_info_manager = "on-disk-manager" # Example of a TPM provider configuration #[[provider]] +# ⚠ +# ⚠ WARNING: Provider name cannot change. +# ⚠ WARNING: Choose a suitable naming scheme for your providers now. +# ⚠ WARNING: Provider name defaults to "tpm-provider" if not provided, you will not be able to change +# ⚠ the provider's name from this if you decide to use the default. +# ⚠ WARNING: Changing provider name after use will lead to loss of existing keys. +# ⚠ +# (Optional) The name of the provider +# name = "tpm-provider" #provider_type = "Tpm" #key_info_manager = "on-disk-manager" # (Required) TPM TCTI device to use with this provider. The string can include configuration values - if no @@ -161,6 +189,15 @@ key_info_manager = "on-disk-manager" # All below parameters depend on what devices, interfaces or parameters are required or supported by # "rust-cryptoauthlib" wrapper for cryptoauthlib and underlying hardware. #[[provider]] +# ⚠ +# ⚠ WARNING: Provider name cannot change. +# ⚠ WARNING: Choose a suitable naming scheme for your providers now. +# ⚠ WARNING: Provider name defaults to "cryptoauthlib-provider" if not provided, you will not be able to change +# ⚠ the provider's name from this if you decide to use the default. +# ⚠ WARNING: Changing provider name after use will lead to loss of existing keys. +# ⚠ +# (Optional) The name of the provider +# name = "cryptoauthlib-provider" #provider_type = "CryptoAuthLib" #key_info_manager = "on-disk-manager" ########## @@ -213,6 +250,15 @@ key_info_manager = "on-disk-manager" # Example of a Trusted Service provider configuration. #[[provider]] +# ⚠ +# ⚠ WARNING: Provider name cannot change. +# ⚠ WARNING: Choose a suitable naming scheme for your providers now. +# ⚠ WARNING: Provider name defaults to "trusted-service-provider" if not provided, you will not be able to change +# ⚠ the provider's name from this if you decide to use the default. +# ⚠ WARNING: Changing provider name after use will lead to loss of existing keys. +# ⚠ +# (Optional) The name of the provider +# name = "trusted-service-provider" # (Required) Type of provider. #provider_type = "TrustedService" diff --git a/src/providers/cryptoauthlib/mod.rs b/src/providers/cryptoauthlib/mod.rs index b27bc06d..bd6f91c6 100644 --- a/src/providers/cryptoauthlib/mod.rs +++ b/src/providers/cryptoauthlib/mod.rs @@ -38,6 +38,8 @@ pub struct Provider { #[derivative(Debug = "ignore")] device: rust_cryptoauthlib::AteccDevice, provider_id: ProviderId, + // The name of the provider set in the config. + provider_name: String, #[derivative(Debug = "ignore")] key_info_store: KeyInfoManagerClient, key_slots: KeySlotStorage, @@ -45,8 +47,15 @@ pub struct Provider { } impl Provider { + /// The default provider name for cryptoauthlib provider + pub const DEFAULT_PROVIDER_NAME: &'static str = "cryptoauthlib-provider"; + + /// The UUID for this provider + pub const PROVIDER_UUID: &'static str = "b8ba81e2-e9f7-4bdd-b096-a29d0019960c"; + /// Creates and initialises an instance of CryptoAuthLibProvider fn new( + provider_name: String, key_info_store: KeyInfoManagerClient, atca_iface: rust_cryptoauthlib::AtcaIfaceCfg, access_key_file_name: Option, @@ -72,6 +81,7 @@ impl Provider { cryptoauthlib_provider = Provider { device, provider_id: ProviderId::CryptoAuthLib, + provider_name, key_info_store, key_slots: KeySlotStorage::new(), supported_opcodes: HashSet::new(), @@ -228,7 +238,7 @@ impl Provide for Provider { trace!("describe ingress"); Ok((ProviderInfo { // Assigned UUID for this provider: b8ba81e2-e9f7-4bdd-b096-a29d0019960c - uuid: Uuid::parse_str("b8ba81e2-e9f7-4bdd-b096-a29d0019960c").or(Err(ResponseStatus::InvalidEncoding))?, + uuid: Uuid::parse_str(Provider::PROVIDER_UUID).or(Err(ResponseStatus::InvalidEncoding))?, description: String::from("User space hardware provider, utilizing MicrochipTech CryptoAuthentication Library for ATECCx08 chips"), vendor: String::from("Arm"), version_maj: 0, @@ -417,6 +427,7 @@ impl Provide for Provider { #[derive(Default, Derivative)] #[derivative(Debug)] pub struct ProviderBuilder { + provider_name: Option, #[derivative(Debug = "ignore")] key_info_store: Option, device_type: Option, @@ -433,6 +444,7 @@ impl ProviderBuilder { /// Create a new CryptoAuthLib builder pub fn new() -> ProviderBuilder { ProviderBuilder { + provider_name: None, key_info_store: None, device_type: None, iface_type: None, @@ -445,6 +457,13 @@ impl ProviderBuilder { } } + /// Add a provider name + pub fn with_provider_name(mut self, provider_name: String) -> ProviderBuilder { + self.provider_name = Some(provider_name); + + self + } + /// Add a KeyInfo manager pub fn with_key_info_store(mut self, key_info_store: KeyInfoManagerClient) -> ProviderBuilder { self.key_info_store = Some(key_info_store); @@ -556,6 +575,9 @@ impl ProviderBuilder { None => return Err(Error::new(ErrorKind::InvalidData, "Missing inteface type")), }; Provider::new( + self.provider_name.ok_or_else(|| { + std::io::Error::new(std::io::ErrorKind::InvalidData, "missing provider name") + })?, self.key_info_store .ok_or_else(|| Error::new(ErrorKind::InvalidData, "missing key info store"))?, iface_cfg, diff --git a/src/providers/mbed_crypto/mod.rs b/src/providers/mbed_crypto/mod.rs index d3e608ae..5b035411 100644 --- a/src/providers/mbed_crypto/mod.rs +++ b/src/providers/mbed_crypto/mod.rs @@ -55,6 +55,9 @@ const SUPPORTED_OPCODES: [Opcode; 15] = [ #[derive(Derivative)] #[derivative(Debug)] pub struct Provider { + // The name of the provider set in the config. + provider_name: String, + // When calling write on a reference of key_info_store, a type // std::sync::RwLockWriteGuard is returned. We need to use the // dereference operator (*) to access the inner type dyn ManageKeyInfo + Send + Sync and then @@ -74,11 +77,17 @@ pub struct Provider { } impl Provider { + /// The default provider name for mbed-crypto provider + pub const DEFAULT_PROVIDER_NAME: &'static str = "mbed-crypto-provider"; + + /// The UUID for this provider + pub const PROVIDER_UUID: &'static str = "1c1139dc-ad7c-47dc-ad6b-db6fdb466552"; + /// Creates and initialise a new instance of MbedCryptoProvider. /// Checks if there are not more keys stored in the Key Info Manager than in the MbedCryptoProvider and /// if there, delete them. Adds Key IDs currently in use in the local IDs store. /// Returns `None` if the initialisation failed. - fn new(key_info_store: KeyInfoManagerClient) -> Option { + fn new(provider_name: String, key_info_store: KeyInfoManagerClient) -> Option { // Safety: this function should be called before any of the other Mbed Crypto functions // are. if let Err(error) = psa_crypto::init() { @@ -86,6 +95,7 @@ impl Provider { return None; } let mbed_crypto_provider = Provider { + provider_name, key_info_store, key_handle_mutex: Mutex::new(()), id_counter: AtomicU32::new(key::PSA_KEY_ID_USER_MIN), @@ -149,7 +159,7 @@ impl Provide for Provider { trace!("describe ingress"); Ok((ProviderInfo { // Assigned UUID for this provider: 1c1139dc-ad7c-47dc-ad6b-db6fdb466552 - uuid: Uuid::parse_str("1c1139dc-ad7c-47dc-ad6b-db6fdb466552").or(Err(ResponseStatus::InvalidEncoding))?, + uuid: Uuid::parse_str(Provider::PROVIDER_UUID).or(Err(ResponseStatus::InvalidEncoding))?, description: String::from("User space software provider, based on Mbed Crypto - the reference implementation of the PSA crypto API"), vendor: String::from("Arm"), version_maj: 0, @@ -319,6 +329,7 @@ impl Provide for Provider { #[derive(Default, Derivative)] #[derivative(Debug)] pub struct ProviderBuilder { + provider_name: Option, #[derivative(Debug = "ignore")] key_info_store: Option, } @@ -327,10 +338,18 @@ impl ProviderBuilder { /// Create a new provider builder pub fn new() -> ProviderBuilder { ProviderBuilder { + provider_name: None, key_info_store: None, } } + /// Add a provider name + pub fn with_provider_name(mut self, provider_name: String) -> ProviderBuilder { + self.provider_name = Some(provider_name); + + self + } + /// Add a KeyInfo manager pub fn with_key_info_store(mut self, key_info_store: KeyInfoManagerClient) -> ProviderBuilder { self.key_info_store = Some(key_info_store); @@ -341,6 +360,9 @@ impl ProviderBuilder { /// Build into a MbedProvider pub fn build(self) -> std::io::Result { Provider::new( + self.provider_name.ok_or_else(|| { + std::io::Error::new(std::io::ErrorKind::InvalidData, "missing provider name") + })?, self.key_info_store .ok_or_else(|| Error::new(ErrorKind::InvalidData, "missing key info store"))?, ) diff --git a/src/providers/pkcs11/mod.rs b/src/providers/pkcs11/mod.rs index 5f6bda02..15586241 100644 --- a/src/providers/pkcs11/mod.rs +++ b/src/providers/pkcs11/mod.rs @@ -58,6 +58,8 @@ const SUPPORTED_OPCODES: [Opcode; 8] = [ #[derive(Derivative)] #[derivative(Debug)] pub struct Provider { + // The name of the provider set in the config. + provider_name: String, #[derivative(Debug = "ignore")] key_info_store: KeyInfoManagerClient, local_ids: RwLock, @@ -70,11 +72,18 @@ pub struct Provider { } impl Provider { + /// The default provider name for pkcs11 provider + pub const DEFAULT_PROVIDER_NAME: &'static str = "pkcs11-provider"; + + /// The UUID for this provider + pub const PROVIDER_UUID: &'static str = "30e39502-eba6-4d60-a4af-c518b7f5e38f"; + /// Creates and initialise a new instance of Pkcs11Provider. /// Checks if there are not more keys stored in the Key Info Manager than in the PKCS 11 library /// and if there are, delete them. Adds Key IDs currently in use in the local IDs store. /// Returns `None` if the initialisation failed. fn new( + provider_name: String, key_info_store: KeyInfoManagerClient, backend: Pkcs11, slot_number: Slot, @@ -92,6 +101,7 @@ impl Provider { #[allow(clippy::mutex_atomic)] let pkcs11_provider = Provider { + provider_name, key_info_store, local_ids: RwLock::new(HashSet::new()), backend, @@ -218,7 +228,7 @@ impl Provide for Provider { Ok(( ProviderInfo { // Assigned UUID for this provider: 30e39502-eba6-4d60-a4af-c518b7f5e38f - uuid: Uuid::parse_str("30e39502-eba6-4d60-a4af-c518b7f5e38f") + uuid: Uuid::parse_str(Provider::PROVIDER_UUID) .or(Err(ResponseStatus::InvalidEncoding))?, description: String::from( "PKCS #11 provider, interfacing with a PKCS #11 library.", @@ -347,6 +357,7 @@ impl Provide for Provider { #[derive(Default, Derivative)] #[derivative(Debug)] pub struct ProviderBuilder { + provider_name: Option, #[derivative(Debug = "ignore")] key_info_store: Option, pkcs11_library_path: Option, @@ -360,6 +371,7 @@ impl ProviderBuilder { /// Create a new Pkcs11Provider builder pub fn new() -> ProviderBuilder { ProviderBuilder { + provider_name: None, key_info_store: None, pkcs11_library_path: None, slot_number: None, @@ -369,6 +381,13 @@ impl ProviderBuilder { } } + /// Add a provider name + pub fn with_provider_name(mut self, provider_name: String) -> ProviderBuilder { + self.provider_name = Some(provider_name); + + self + } + /// Add a KeyInfo manager pub fn with_key_info_store(mut self, key_info_store: KeyInfoManagerClient) -> ProviderBuilder { self.key_info_store = Some(key_info_store); @@ -474,6 +493,9 @@ impl ProviderBuilder { }; Ok(Provider::new( + self.provider_name.ok_or_else(|| { + std::io::Error::new(std::io::ErrorKind::InvalidData, "missing provider name") + })?, self.key_info_store .ok_or_else(|| Error::new(ErrorKind::InvalidData, "missing key info store"))?, backend, diff --git a/src/providers/tpm/mod.rs b/src/providers/tpm/mod.rs index dedd61c3..c5851876 100644 --- a/src/providers/tpm/mod.rs +++ b/src/providers/tpm/mod.rs @@ -56,6 +56,9 @@ const AUTH_HEX_PREFIX: &str = "hex:"; #[derive(Derivative)] #[derivative(Debug)] pub struct Provider { + // The name of the provider set in the config. + provider_name: String, + // The Mutex is needed both because interior mutability is needed to the ESAPI Context // structure that is shared between threads and because two threads are not allowed the same // ESAPI context simultaneously. @@ -67,12 +70,20 @@ pub struct Provider { } impl Provider { + /// The default provider name for tpm provider + pub const DEFAULT_PROVIDER_NAME: &'static str = "tpm-provider"; + + /// The UUID for this provider + pub const PROVIDER_UUID: &'static str = "1e4954a4-ff21-46d3-ab0c-661eeb667e1d"; + // Creates and initialise a new instance of TpmProvider. fn new( + provider_name: String, key_info_store: KeyInfoManagerClient, esapi_context: tss_esapi::TransientKeyContext, ) -> Provider { Provider { + provider_name, esapi_context: Mutex::new(esapi_context), key_info_store, } @@ -84,7 +95,7 @@ impl Provide for Provider { trace!("describe ingress"); Ok((ProviderInfo { // Assigned UUID for this provider: 1e4954a4-ff21-46d3-ab0c-661eeb667e1d - uuid: Uuid::parse_str("1e4954a4-ff21-46d3-ab0c-661eeb667e1d").or(Err(ResponseStatus::InvalidEncoding))?, + uuid: Uuid::parse_str(Provider::PROVIDER_UUID).or(Err(ResponseStatus::InvalidEncoding))?, description: String::from("TPM provider, interfacing with a library implementing the TCG TSS 2.0 Enhanced System API specification."), vendor: String::from("Trusted Computing Group (TCG)"), version_maj: 0, @@ -204,6 +215,7 @@ impl Drop for Provider { #[derive(Default, Derivative)] #[derivative(Debug)] pub struct ProviderBuilder { + provider_name: Option, #[derivative(Debug = "ignore")] key_info_store: Option, tcti: Option, @@ -214,12 +226,20 @@ impl ProviderBuilder { /// Create a new TPM provider builder pub fn new() -> ProviderBuilder { ProviderBuilder { + provider_name: None, key_info_store: None, tcti: None, owner_hierarchy_auth: None, } } + /// Add a provider name + pub fn with_provider_name(mut self, provider_name: String) -> ProviderBuilder { + self.provider_name = Some(provider_name); + + self + } + /// Add a KeyInfo manager pub fn with_key_info_store(mut self, key_info_store: KeyInfoManagerClient) -> ProviderBuilder { self.key_info_store = Some(key_info_store); @@ -315,6 +335,9 @@ impl ProviderBuilder { self.tcti.zeroize(); self.owner_hierarchy_auth.zeroize(); Ok(Provider::new( + self.provider_name.ok_or_else(|| { + std::io::Error::new(std::io::ErrorKind::InvalidData, "missing provider name") + })?, self.key_info_store.ok_or_else(|| { std::io::Error::new(ErrorKind::InvalidData, "missing key info store") })?, diff --git a/src/providers/trusted_service/mod.rs b/src/providers/trusted_service/mod.rs index 09aea1e7..4684f68e 100644 --- a/src/providers/trusted_service/mod.rs +++ b/src/providers/trusted_service/mod.rs @@ -35,7 +35,6 @@ const SUPPORTED_OPCODES: [Opcode; 8] = [ Opcode::PsaExportKey, Opcode::PsaGenerateRandom, ]; - /// Trusted Service provider structure /// /// Operations for this provider are serviced through an IPC interface that leads @@ -43,6 +42,9 @@ const SUPPORTED_OPCODES: [Opcode; 8] = [ #[derive(Derivative)] #[derivative(Debug)] pub struct Provider { + // The name of the provider set in the config. + provider_name: String, + context: Context, // When calling write on a reference of key_info_store, a type // std::sync::RwLockWriteGuard is returned. We need to use the @@ -57,9 +59,19 @@ pub struct Provider { } impl Provider { + /// The default provider name for trusted service provider + pub const DEFAULT_PROVIDER_NAME: &'static str = "trusted-service-provider"; + + /// The UUID for this provider + pub const PROVIDER_UUID: &'static str = "71129441-508a-4da6-b6e8-7b98a777e4c0"; + /// Creates and initialises a new instance of Provider. - fn new(key_info_store: KeyInfoManagerClient) -> anyhow::Result { + fn new( + provider_name: String, + key_info_store: KeyInfoManagerClient, + ) -> anyhow::Result { let ts_provider = Provider { + provider_name, key_info_store, context: Context::connect()?, id_counter: AtomicU32::new(key::PSA_KEY_ID_USER_MIN), @@ -108,7 +120,7 @@ impl Provide for Provider { trace!("describe ingress"); Ok((ProviderInfo { // Assigned UUID for this provider: 71129441-508a-4da6-b6e8-7b98a777e4c0 - uuid: Uuid::parse_str("71129441-508a-4da6-b6e8-7b98a777e4c0")?, + uuid: Uuid::parse_str(Provider::PROVIDER_UUID)?, description: String::from("Provider exposing functionality provided by the Crypto Trusted Service running in a Trusted Execution Environment"), vendor: String::from("Arm"), version_maj: 0, @@ -217,6 +229,7 @@ impl Provide for Provider { #[derive(Default, Derivative)] #[derivative(Debug)] pub struct ProviderBuilder { + provider_name: Option, #[derivative(Debug = "ignore")] key_info_store: Option, } @@ -225,10 +238,18 @@ impl ProviderBuilder { /// Create a new provider builder pub fn new() -> ProviderBuilder { ProviderBuilder { + provider_name: None, key_info_store: None, } } + /// Add a provider name + pub fn with_provider_name(mut self, provider_name: String) -> ProviderBuilder { + self.provider_name = Some(provider_name); + + self + } + /// Add a KeyInfo manager pub fn with_key_info_store(mut self, key_info_store: KeyInfoManagerClient) -> ProviderBuilder { self.key_info_store = Some(key_info_store); @@ -238,8 +259,13 @@ impl ProviderBuilder { /// Build into a TrustedService pub fn build(self) -> anyhow::Result { - Provider::new(self.key_info_store.ok_or_else(|| { - std::io::Error::new(std::io::ErrorKind::InvalidData, "missing key info store") - })?) + Provider::new( + self.provider_name.ok_or_else(|| { + std::io::Error::new(std::io::ErrorKind::InvalidData, "missing provider name") + })?, + self.key_info_store.ok_or_else(|| { + std::io::Error::new(std::io::ErrorKind::InvalidData, "missing key info store") + })?, + ) } } diff --git a/src/utils/config.rs b/src/utils/config.rs index ebbb17a8..3664f8f7 100644 --- a/src/utils/config.rs +++ b/src/utils/config.rs @@ -2,9 +2,36 @@ // SPDX-License-Identifier: Apache-2.0 //! Structures for the Parsec configuration file +#[cfg(feature = "cryptoauthlib-provider")] +use crate::providers::cryptoauthlib::Provider as CryptoAuthLibProvider; +#[cfg(feature = "mbed-crypto-provider")] +use crate::providers::mbed_crypto::Provider as MbedCryptoProvider; +#[cfg(feature = "pkcs11-provider")] +use crate::providers::pkcs11::Provider as Pkcs11Provider; +#[cfg(feature = "tpm-provider")] +use crate::providers::tpm::Provider as TpmProvider; +#[cfg(feature = "trusted-service-provider")] +use crate::providers::trusted_service::Provider as TrustedServiceProvider; +#[cfg(not(all( + feature = "mbed-crypto-provider", + feature = "pkcs11-provider", + feature = "tpm-provider", + feature = "cryptoauthlib-provider", + feature = "trusted-service-provider" +)))] +use log::error; use log::LevelFilter; use parsec_interface::requests::ProviderId; use serde::Deserialize; +use std::io::Error; +#[cfg(not(all( + feature = "mbed-crypto-provider", + feature = "pkcs11-provider", + feature = "tpm-provider", + feature = "cryptoauthlib-provider", + feature = "trusted-service-provider" +)))] +use std::io::ErrorKind; use zeroize::Zeroize; /// Core settings @@ -108,11 +135,15 @@ pub struct KeyInfoManagerConfig { pub enum ProviderConfig { /// Mbed Crypto provider configuration MbedCrypto { + /// The name of the provider + name: Option, /// Name of the Key Info Manager to use key_info_manager: String, }, /// PKCS 11 provider configuration Pkcs11 { + /// The name of the provider + name: Option, /// Name of the Key Info Manager to use key_info_manager: String, /// Path of the PKCS 11 library @@ -128,6 +159,8 @@ pub enum ProviderConfig { }, /// TPM provider configuration Tpm { + /// The name of the provider + name: Option, /// Name of the Key Info Manager to use key_info_manager: String, /// TCTI to use with the provider @@ -140,6 +173,8 @@ pub enum ProviderConfig { }, /// Microchip CryptoAuthentication Library provider configuration CryptoAuthLib { + /// The name of the provider + name: Option, /// Name of the Key Info Manager to use key_info_manager: String, /// ATECC Device type @@ -161,6 +196,8 @@ pub enum ProviderConfig { }, /// Trusted Service provider configuration TrustedService { + /// The name of the provider + name: Option, /// Name of Key Info Manager to use key_info_manager: String, }, @@ -202,6 +239,43 @@ impl ProviderConfig { ProviderConfig::TrustedService { .. } => ProviderId::TrustedService, } } + /// Get the name of the Provider + /// If there is not one set, use the default. + pub fn provider_name(&self) -> Result { + match *self { + #[cfg(feature = "mbed-crypto-provider")] + ProviderConfig::MbedCrypto { ref name, .. } => Ok(name + .clone() + .unwrap_or_else(|| String::from(MbedCryptoProvider::DEFAULT_PROVIDER_NAME))), + #[cfg(feature = "pkcs11-provider")] + ProviderConfig::Pkcs11 { ref name, .. } => Ok(name + .clone() + .unwrap_or_else(|| String::from(Pkcs11Provider::DEFAULT_PROVIDER_NAME))), + #[cfg(feature = "tpm-provider")] + ProviderConfig::Tpm { ref name, .. } => Ok(name + .clone() + .unwrap_or_else(|| String::from(TpmProvider::DEFAULT_PROVIDER_NAME))), + #[cfg(feature = "cryptoauthlib-provider")] + ProviderConfig::CryptoAuthLib { ref name, .. } => Ok(name + .clone() + .unwrap_or_else(|| String::from(CryptoAuthLibProvider::DEFAULT_PROVIDER_NAME))), + #[cfg(feature = "trusted-service-provider")] + ProviderConfig::TrustedService { ref name, .. } => Ok(name + .clone() + .unwrap_or_else(|| String::from(TrustedServiceProvider::DEFAULT_PROVIDER_NAME))), + #[cfg(not(all( + feature = "mbed-crypto-provider", + feature = "pkcs11-provider", + feature = "tpm-provider", + feature = "cryptoauthlib-provider", + feature = "trusted-service-provider" + )))] + _ => { + error!("Provider chosen in the configuration was not compiled in Parsec binary."); + Err(Error::new(ErrorKind::InvalidData, "provider not compiled")) + } + } + } } /// Configuration of Parsec diff --git a/src/utils/service_builder.rs b/src/utils/service_builder.rs index 8b394cf1..5fa9a32a 100644 --- a/src/utils/service_builder.rs +++ b/src/utils/service_builder.rs @@ -26,6 +26,7 @@ use parsec_interface::operations_protobuf::ProtobufConverter; use parsec_interface::requests::AuthType; use parsec_interface::requests::{BodyType, ProviderId}; use std::collections::HashMap; +use std::collections::HashSet; use std::io::{Error, ErrorKind}; use std::sync::Arc; use std::time::Duration; @@ -208,17 +209,21 @@ fn build_providers( configs: &[ProviderConfig], kim_factorys: HashMap, ) -> Result> { - let mut list = Vec::new(); + let mut providers = Vec::new(); + let mut provider_names = HashSet::new(); for config in configs { + // Check for duplicate providers. let provider_id = config.provider_id(); - if list.iter().any(|(id, _)| *id == provider_id) { - error!("Parsec currently only supports one instance of each provider type, but {} was supplied twice. Please check your config.toml file.", provider_id); - return Err(Error::new( - ErrorKind::InvalidData, - "only one provider per type is supported", - ) - .into()); + + // Check for duplicate provider names. + let provider_name = config.provider_name()?; + if provider_names.contains(&provider_name) { + error!("Duplicate provider names found.\n{} was found twice.\nThe \'[[provider]] name config option can be used to differentiate between providers of the same type.\nPlease check your config.toml file.", provider_name); + return Err( + Error::new(ErrorKind::InvalidData, "duplicate provider names found").into(), + ); } + let _ = provider_names.insert(provider_name.clone()); let kim_factory = match kim_factorys.get(config.key_info_manager()) { Some(kim_factory) => kim_factory, @@ -249,10 +254,10 @@ fn build_providers( return Err(Error::new(ErrorKind::Other, "failed to create provider").into()); } }; - let _ = list.push((provider_id, provider)); + let _ = providers.push((provider_id, provider)); } - Ok(list) + Ok(providers) } // This cfg_attr is used to allow the fact that key_info_manager is not used when there is no @@ -280,6 +285,7 @@ unsafe fn get_provider( Ok(Some(Arc::new( MbedCryptoProviderBuilder::new() .with_key_info_store(kim_factory.build_client(ProviderId::MbedCrypto)) + .with_provider_name(config.provider_name()?) .build()?, ))) } @@ -296,6 +302,7 @@ unsafe fn get_provider( Ok(Some(Arc::new( Pkcs11ProviderBuilder::new() .with_key_info_store(kim_factory.build_client(ProviderId::Pkcs11)) + .with_provider_name(config.provider_name()?) .with_pkcs11_library_path(library_path.clone()) .with_slot_number(*slot_number) .with_user_pin(user_pin.clone()) @@ -336,6 +343,7 @@ unsafe fn get_provider( Ok(Some(Arc::new( TpmProviderBuilder::new() .with_key_info_store(kim_factory.build_client(ProviderId::Tpm)) + .with_provider_name(config.provider_name()?) .with_tcti(tcti) .with_owner_hierarchy_auth(owner_hierarchy_auth.clone()) .build()?, @@ -357,6 +365,7 @@ unsafe fn get_provider( Ok(Some(Arc::new( CryptoAuthLibProviderBuilder::new() .with_key_info_store(kim_factory.build_client(ProviderId::CryptoAuthLib)) + .with_provider_name(config.provider_name()?) .with_device_type(device_type.to_string()) .with_iface_type(iface_type.to_string()) .with_wake_delay(*wake_delay) @@ -374,6 +383,7 @@ unsafe fn get_provider( Ok(Some(Arc::new( TrustedServiceProviderBuilder::new() .with_key_info_store(kim_factory.build_client(ProviderId::TrustedService)) + .with_provider_name(config.provider_name()?) .build()?, ))) }