From f8548abcab702ccaf75fd84493fdb409caf6bb22 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/back/backend_handler.rs | 12 ++++++ src/providers/cryptoauthlib/mod.rs | 27 ++++++++++++- src/providers/mbed_crypto/mod.rs | 29 +++++++++++++- src/providers/pkcs11/mod.rs | 28 ++++++++++++- src/providers/tpm/mod.rs | 28 ++++++++++++- src/providers/trusted_service/mod.rs | 41 ++++++++++++++++--- src/utils/config.rs | 60 +++++++++++++++++++++++++++- src/utils/service_builder.rs | 29 +++++++++++--- 9 files changed, 283 insertions(+), 17 deletions(-) diff --git a/config.toml b/config.toml index 5d59bad0..d5c76b9e 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. @@ -134,6 +153,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 @@ -160,6 +188,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" ########## @@ -212,6 +249,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/back/backend_handler.rs b/src/back/backend_handler.rs index ef5317d3..21c01535 100644 --- a/src/back/backend_handler.rs +++ b/src/back/backend_handler.rs @@ -33,6 +33,7 @@ pub struct BackEndHandler { provider: Arc, #[derivative(Debug = "ignore")] converter: Box, + provider_name: String, provider_id: ProviderId, content_type: BodyType, accept_type: BodyType, @@ -291,6 +292,7 @@ pub struct BackEndHandlerBuilder { #[derivative(Debug = "ignore")] converter: Option>, provider_id: Option, + provider_name: Option, content_type: Option, accept_type: Option, } @@ -302,6 +304,7 @@ impl BackEndHandlerBuilder { provider: None, converter: None, provider_id: None, + provider_name: None, content_type: None, accept_type: None, } @@ -325,6 +328,12 @@ impl BackEndHandlerBuilder { self } + /// Set the provider name of the BackEndHandler + pub fn with_provider_name(mut self, provider_name: String) -> Self { + self.provider_name = Some(provider_name); + self + } + /// Set the content type that the BackEndHandler supports pub fn with_content_type(mut self, content_type: BodyType) -> Self { self.content_type = Some(content_type); @@ -349,6 +358,9 @@ impl BackEndHandlerBuilder { provider_id: self .provider_id .ok_or_else(|| Error::new(ErrorKind::InvalidData, "provider_id is missing"))?, + provider_name: self + .provider_name + .ok_or_else(|| Error::new(ErrorKind::InvalidData, "provider_name is missing"))?, content_type: self .content_type .ok_or_else(|| Error::new(ErrorKind::InvalidData, "content_type is missing"))?, diff --git a/src/providers/cryptoauthlib/mod.rs b/src/providers/cryptoauthlib/mod.rs index b27bc06d..58725d51 100644 --- a/src/providers/cryptoauthlib/mod.rs +++ b/src/providers/cryptoauthlib/mod.rs @@ -31,6 +31,9 @@ mod key_management; mod key_slot; mod key_slot_storage; +// The UUID for this provider +const PROVIDER_UUID: &str = "b8ba81e2-e9f7-4bdd-b096-a29d0019960c"; + /// CryptoAuthLib provider structure #[derive(Derivative)] #[derivative(Debug)] @@ -38,6 +41,10 @@ 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, + // The UUID of the provider. + provider_uuid: String, #[derivative(Debug = "ignore")] key_info_store: KeyInfoManagerClient, key_slots: KeySlotStorage, @@ -45,8 +52,12 @@ pub struct Provider { } impl Provider { + /// The default provider name for cryptoauthlib provider + pub const DEFAULT_PROVIDER_NAME: &'static str = "cryptoauthlib-provider"; + /// 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 +83,8 @@ impl Provider { cryptoauthlib_provider = Provider { device, provider_id: ProviderId::CryptoAuthLib, + provider_uuid: String::from(PROVIDER_UUID), + provider_name, key_info_store, key_slots: KeySlotStorage::new(), supported_opcodes: HashSet::new(), @@ -228,7 +241,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_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 +430,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 +447,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 +460,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 +578,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..2441dc82 100644 --- a/src/providers/mbed_crypto/mod.rs +++ b/src/providers/mbed_crypto/mod.rs @@ -51,10 +51,18 @@ const SUPPORTED_OPCODES: [Opcode; 15] = [ Opcode::PsaGenerateRandom, ]; +// The UUID for this provider +const PROVIDER_UUID: &str = "1c1139dc-ad7c-47dc-ad6b-db6fdb466552"; + /// Mbed Crypto provider structure #[derive(Derivative)] #[derivative(Debug)] pub struct Provider { + // The name of the provider set in the config. + provider_name: String, + // The UUID of the provider. + provider_uuid: 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 +82,14 @@ pub struct Provider { } impl Provider { + /// The default provider name for mbed-crypto provider + pub const DEFAULT_PROVIDER_NAME: &'static str = "mbed-crypto-provider"; + /// 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 +97,8 @@ impl Provider { return None; } let mbed_crypto_provider = Provider { + provider_name, + provider_uuid: String::from(PROVIDER_UUID), key_info_store, key_handle_mutex: Mutex::new(()), id_counter: AtomicU32::new(key::PSA_KEY_ID_USER_MIN), @@ -149,7 +162,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_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 +332,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 +341,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 +363,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 1e807697..8301108d 100644 --- a/src/providers/pkcs11/mod.rs +++ b/src/providers/pkcs11/mod.rs @@ -49,6 +49,9 @@ const SUPPORTED_OPCODES: [Opcode; 8] = [ Opcode::PsaAsymmetricEncrypt, ]; +// The UUID for this provider +const PROVIDER_UUID: &str = "30e39502-eba6-4d60-a4af-c518b7f5e38f"; + /// Provider for Public Key Cryptography Standard #11 /// /// Operations for this provider are serviced through a PKCS11 interface, @@ -57,6 +60,10 @@ const SUPPORTED_OPCODES: [Opcode; 8] = [ #[derive(Derivative)] #[derivative(Debug)] pub struct Provider { + // The name of the provider set in the config. + provider_name: String, + // The UUID of the provider. + provider_uuid: String, #[derivative(Debug = "ignore")] key_info_store: KeyInfoManagerClient, local_ids: RwLock, @@ -69,11 +76,15 @@ pub struct Provider { } impl Provider { + /// The default provider name for pkcs11 provider + pub const DEFAULT_PROVIDER_NAME: &'static str = "pkcs11-provider"; + /// 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, @@ -91,6 +102,8 @@ impl Provider { #[allow(clippy::mutex_atomic)] let pkcs11_provider = Provider { + provider_name, + provider_uuid: String::from(PROVIDER_UUID), key_info_store, local_ids: RwLock::new(HashSet::new()), backend, @@ -217,8 +230,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") - .or(Err(ResponseStatus::InvalidEncoding))?, + uuid: Uuid::parse_str(PROVIDER_UUID).or(Err(ResponseStatus::InvalidEncoding))?, description: String::from( "PKCS #11 provider, interfacing with a PKCS #11 library.", ), @@ -346,6 +358,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, @@ -359,6 +372,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, @@ -368,6 +382,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); @@ -450,6 +471,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..939d7241 100644 --- a/src/providers/tpm/mod.rs +++ b/src/providers/tpm/mod.rs @@ -47,6 +47,9 @@ const ROOT_KEY_AUTH_SIZE: usize = 32; const AUTH_STRING_PREFIX: &str = "str:"; const AUTH_HEX_PREFIX: &str = "hex:"; +// The UUID for this provider +const PROVIDER_UUID: &str = "1e4954a4-ff21-46d3-ab0c-661eeb667e1d"; + /// Provider for Trusted Platform Modules /// /// Operations for this provider are serviced using the TPM 2.0 software stack, @@ -56,6 +59,11 @@ 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 UUID of the provider. + provider_uuid: 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 +75,18 @@ pub struct Provider { } impl Provider { + /// The default provider name for tpm provider + pub const DEFAULT_PROVIDER_NAME: &'static str = "tpm-provider"; + // 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, + provider_uuid: String::from(PROVIDER_UUID), esapi_context: Mutex::new(esapi_context), key_info_store, } @@ -84,7 +98,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_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 +218,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 +229,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 +338,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..f4e7d076 100644 --- a/src/providers/trusted_service/mod.rs +++ b/src/providers/trusted_service/mod.rs @@ -36,6 +36,9 @@ const SUPPORTED_OPCODES: [Opcode; 8] = [ Opcode::PsaGenerateRandom, ]; +// The UUID for this provider +const PROVIDER_UUID: &str = "71129441-508a-4da6-b6e8-7b98a777e4c0"; + /// Trusted Service provider structure /// /// Operations for this provider are serviced through an IPC interface that leads @@ -43,6 +46,12 @@ const SUPPORTED_OPCODES: [Opcode; 8] = [ #[derive(Derivative)] #[derivative(Debug)] pub struct Provider { + // The name of the provider set in the config. + provider_name: String, + + // The UUID of the provider. + provider_uuid: 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 +66,17 @@ pub struct Provider { } impl Provider { + /// The default provider name for trusted service provider + pub const DEFAULT_PROVIDER_NAME: &'static str = "trusted-service-provider"; + /// 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, + provider_uuid: String::from(PROVIDER_UUID), key_info_store, context: Context::connect()?, id_counter: AtomicU32::new(key::PSA_KEY_ID_USER_MIN), @@ -108,7 +125,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_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 +234,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 +243,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 +264,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 c02776b9..563904fd 100644 --- a/src/utils/config.rs +++ b/src/utils/config.rs @@ -2,9 +2,20 @@ // SPDX-License-Identifier: Apache-2.0 //! Structures for the Parsec configuration file -use log::LevelFilter; +#[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; +use log::{error, LevelFilter}; use parsec_interface::requests::ProviderId; use serde::Deserialize; +use std::io::{Error, ErrorKind}; use zeroize::Zeroize; /// Core settings @@ -108,11 +119,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 +143,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 +157,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 +180,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 +223,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."); + return Err(Error::new(ErrorKind::InvalidData, "provider not compiled").into()); + } + } + } } /// Configuration of Parsec diff --git a/src/utils/service_builder.rs b/src/utils/service_builder.rs index afbc2786..f9846083 100644 --- a/src/utils/service_builder.rs +++ b/src/utils/service_builder.rs @@ -163,7 +163,7 @@ impl ServiceBuilder { } fn build_backend_handlers( - mut providers: Vec<(ProviderId, Provider)>, + mut providers: Vec<(ProviderId, Provider, String)>, authenticators: &[(AuthType, Authenticator)], ) -> Result> { let mut map = HashMap::new(); @@ -178,13 +178,14 @@ fn build_backend_handlers( core_provider_builder = core_provider_builder.with_authenticator_info(authenticator_info); } - for (provider_id, provider) in providers.drain(..) { + for (provider_id, provider, provider_name) in providers.drain(..) { core_provider_builder = core_provider_builder.with_provider(provider.clone()); let backend_handler = BackEndHandlerBuilder::new() .with_provider(provider) .with_converter(Box::from(ProtobufConverter {})) .with_provider_id(provider_id) + .with_provider_name(provider_name) .with_content_type(BodyType::Protobuf) .with_accept_type(BodyType::Protobuf) .build()?; @@ -195,6 +196,7 @@ fn build_backend_handlers( .with_provider(Arc::new(core_provider_builder.build()?)) .with_converter(Box::from(ProtobufConverter {})) .with_provider_id(ProviderId::Core) + .with_provider_name(String::from("core-provider")) .with_content_type(BodyType::Protobuf) .with_accept_type(BodyType::Protobuf) .build()?; @@ -207,11 +209,13 @@ fn build_backend_handlers( fn build_providers( configs: &[ProviderConfig], kim_factorys: HashMap, -) -> Result> { +) -> Result> { let mut list = Vec::new(); + let mut provider_names = Vec::new(); for config in configs { + // Check for duplicate providers. let provider_id = config.provider_id(); - if list.iter().any(|(id, _)| *id == 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, @@ -220,6 +224,16 @@ fn build_providers( .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(), + ); + } + provider_names.push(provider_name.clone()); + let kim_factory = match kim_factorys.get(config.key_info_manager()) { Some(kim_factory) => kim_factory, None => { @@ -249,7 +263,7 @@ fn build_providers( return Err(Error::new(ErrorKind::Other, "failed to create provider").into()); } }; - let _ = list.push((provider_id, provider)); + let _ = list.push((provider_id, provider, provider_name)); } Ok(list) @@ -280,6 +294,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()?, ))) } @@ -298,6 +313,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).try_into()?) .with_user_pin(user_pin.clone()) @@ -338,6 +354,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()?, @@ -359,6 +376,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) @@ -376,6 +394,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()?, ))) }