From 3620599c2122626cff8488ca8acfb6b3227dff62 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Fri, 30 Jul 2021 11:42:00 +0100 Subject: [PATCH] Added KeyIdentity to replace KeyTriple KeyIdentity contains a ApplicationIdentity, ProviderIdentity and a key_name. KeyTriple still exists but solely for the use by the on_disk_manager KIM. This is preliminary work towards the new SQLite KIM as part of #486 Closes #488 Signed-off-by: Matt Davis --- .../direct_authenticator/mod.rs | 32 +- .../jwt_svid_authenticator/mod.rs | 10 +- src/authenticators/mod.rs | 110 +++--- .../mod.rs | 29 +- src/back/backend_handler.rs | 46 +-- src/front/front_end.rs | 4 +- src/key_info_managers/mod.rs | 142 +++++--- src/key_info_managers/on_disk_manager/mod.rs | 318 +++++++++++++++--- src/providers/core/mod.rs | 28 +- src/providers/cryptoauthlib/asym_sign.rs | 26 +- src/providers/cryptoauthlib/key_management.rs | 32 +- src/providers/cryptoauthlib/mod.rs | 58 ++-- src/providers/mbed_crypto/aead.rs | 22 +- src/providers/mbed_crypto/asym_encryption.rs | 22 +- src/providers/mbed_crypto/asym_sign.rs | 22 +- src/providers/mbed_crypto/key_agreement.rs | 14 +- src/providers/mbed_crypto/key_management.rs | 46 ++- src/providers/mbed_crypto/mod.rs | 70 ++-- src/providers/mod.rs | 101 +++++- src/providers/pkcs11/asym_encryption.rs | 30 +- src/providers/pkcs11/asym_sign.rs | 30 +- src/providers/pkcs11/key_management.rs | 42 ++- src/providers/pkcs11/mod.rs | 58 ++-- src/providers/tpm/asym_encryption.rs | 22 +- src/providers/tpm/asym_sign.rs | 22 +- src/providers/tpm/key_management.rs | 52 ++- src/providers/tpm/mod.rs | 50 +-- src/providers/trusted_service/asym_sign.rs | 22 +- .../trusted_service/key_management.rs | 46 ++- src/providers/trusted_service/mod.rs | 52 +-- src/utils/service_builder.rs | 51 ++- 31 files changed, 1107 insertions(+), 502 deletions(-) diff --git a/src/authenticators/direct_authenticator/mod.rs b/src/authenticators/direct_authenticator/mod.rs index 8f283638..c72a0b69 100644 --- a/src/authenticators/direct_authenticator/mod.rs +++ b/src/authenticators/direct_authenticator/mod.rs @@ -8,7 +8,7 @@ //! This authenticator does not offer any security value and should only be used in environments //! where all the clients and the service are mutually trustworthy. -use super::{AdminList, Application, Authenticate}; +use super::{AdminList, Application, ApplicationIdentity, Authenticate}; use crate::front::listener::ConnectionMetadata; use crate::utils::config::Admin; use log::error; @@ -61,7 +61,13 @@ impl Authenticate for DirectAuthenticator { Ok(str) => { let app_name = String::from(str); let is_admin = self.admins.is_admin(&app_name); - Ok(Application::new(app_name, is_admin)) + Ok(Application { + identity: ApplicationIdentity { + name: app_name, + authenticator_id: AuthType::Direct as u8, + }, + is_admin, + }) } Err(_) => { error!("Error parsing the authentication value as a UTF-8 string."); @@ -76,7 +82,6 @@ impl Authenticate for DirectAuthenticator { mod test { use super::super::Authenticate; use super::DirectAuthenticator; - use crate::authenticators::ApplicationName; use parsec_interface::requests::request::RequestAuth; use parsec_interface::requests::ResponseStatus; @@ -90,12 +95,12 @@ mod test { let req_auth = RequestAuth::new(app_name.clone().into_bytes()); let conn_metadata = None; - let app = authenticator + let application = authenticator .authenticate(&req_auth, conn_metadata) .expect("Failed to authenticate"); - assert_eq!(app.get_name(), &ApplicationName::from_name(app_name)); - assert!(!app.is_admin); + assert_eq!(application.identity.name, app_name); + assert!(!application.is_admin); } #[test] @@ -136,22 +141,19 @@ mod test { let req_auth = RequestAuth::new(app_name.clone().into_bytes()); let conn_metadata = None; - let auth_name = authenticator + let application = authenticator .authenticate(&req_auth, conn_metadata) .expect("Failed to authenticate"); - assert_eq!(auth_name.get_name(), &ApplicationName::from_name(app_name)); - assert!(!auth_name.is_admin); + assert_eq!(application.identity.name, app_name); + assert!(!application.is_admin); let req_auth = RequestAuth::new(admin_name.clone().into_bytes()); - let auth_name = authenticator + let application = authenticator .authenticate(&req_auth, conn_metadata) .expect("Failed to authenticate"); - assert_eq!( - auth_name.get_name(), - &ApplicationName::from_name(admin_name) - ); - assert!(auth_name.is_admin); + assert_eq!(application.identity.name, admin_name); + assert!(application.is_admin); } } diff --git a/src/authenticators/jwt_svid_authenticator/mod.rs b/src/authenticators/jwt_svid_authenticator/mod.rs index 42619fca..82eda517 100644 --- a/src/authenticators/jwt_svid_authenticator/mod.rs +++ b/src/authenticators/jwt_svid_authenticator/mod.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 //! JWT SVID authenticator -use super::{Admin, AdminList, Application, Authenticate}; +use super::{Admin, AdminList, Application, ApplicationIdentity, Authenticate}; use crate::front::listener::ConnectionMetadata; use log::error; use parsec_interface::operations::list_authenticators; @@ -72,6 +72,12 @@ impl Authenticate for JwtSvidAuthenticator { })?; let app_name = spiffe_id.to_string(); let is_admin = self.admins.is_admin(&app_name); - Ok(Application::new(app_name, is_admin)) + Ok(Application { + identity: ApplicationIdentity { + name: app_name, + authenticator_id: AuthType::JwtSvid as u8, + }, + is_admin, + }) } } diff --git a/src/authenticators/mod.rs b/src/authenticators/mod.rs index 362ad568..f1ebb25d 100644 --- a/src/authenticators/mod.rs +++ b/src/authenticators/mod.rs @@ -4,7 +4,7 @@ //! //! [Authenticators](https://parallaxsecond.github.io/parsec-book/parsec_service/authenticators.html) //! provide functionality to the service for verifying the authenticity of requests. -//! The result of an authentication is an `ApplicationName` which is parsed by the authenticator and +//! The result of an authentication is an `Application` which is parsed by the authenticator and //! used throughout the service for identifying the request initiator. The input to an authentication //! is the `RequestAuth` field of a request, which is parsed by the authenticator specified in the header. //! The authentication functionality is abstracted through an `Authenticate` trait. @@ -30,29 +30,84 @@ use crate::utils::config::Admin; use parsec_interface::operations::list_authenticators; use parsec_interface::requests::request::RequestAuth; use parsec_interface::requests::Result; +use std::fmt; use std::ops::Deref; -/// String wrapper for app names -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct ApplicationName { +/// A unique identifier for an application. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ApplicationIdentity { + /// The name of the application. name: String, + /// The id of the authenticator used to authenticate the application name. + authenticator_id: u8, } -impl Deref for ApplicationName { - type Target = String; +impl fmt::Display for ApplicationIdentity { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "ApplicationIdentity: [name=\"{}\", authenticator_id=\"{}\"]", + self.name, self.authenticator_id + ) + } +} - fn deref(&self) -> &Self::Target { +impl ApplicationIdentity { + /// Creates a new instance of ProviderIdentity. + pub fn new(name: String, authenticator_id: u8) -> ApplicationIdentity { + ApplicationIdentity { + name, + authenticator_id, + } + } + + /// Get the identity of the application + pub fn name(&self) -> &String { &self.name } + + /// Get whether the application has administrator rights + pub fn authenticator_id(&self) -> &u8 { + &self.authenticator_id + } } /// Wrapper for a Parsec application #[derive(Debug, Clone)] pub struct Application { - name: ApplicationName, + /// The identity of the Application + identity: ApplicationIdentity, + /// Whether the application has administrator rights is_admin: bool, } +impl fmt::Display for Application { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "Application {{identity: {}, is_admin: {}}}", + self.identity, self.is_admin + ) + } +} + +impl Application { + /// Creates a new instance of ProviderIdentity. + pub fn new(identity: ApplicationIdentity, is_admin: bool) -> Application { + Application { identity, is_admin } + } + + /// Get the identity of the application + pub fn identity(&self) -> &ApplicationIdentity { + &self.identity + } + + /// Get whether the application has administrator rights + pub fn is_admin(&self) -> &bool { + &self.is_admin + } +} + /// Authentication interface /// /// Interface that must be implemented for each authentication type available for the service. @@ -78,45 +133,6 @@ pub trait Authenticate { ) -> Result; } -impl ApplicationName { - /// Create ApplicationName from name string only - pub fn from_name(name: String) -> ApplicationName { - ApplicationName { name } - } -} - -impl Application { - /// Create a new Application structure - pub fn new(name: String, is_admin: bool) -> Application { - Application { - name: ApplicationName::from_name(name), - is_admin, - } - } - - /// Check whether the application is an admin - pub fn is_admin(&self) -> bool { - self.is_admin - } - - /// Get a reference to the inner ApplicationName string - pub fn get_name(&self) -> &ApplicationName { - &self.name - } -} - -impl From for ApplicationName { - fn from(auth: Application) -> Self { - auth.name - } -} - -impl std::fmt::Display for ApplicationName { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.name) - } -} - #[derive(Debug, Clone, Default)] struct AdminList(Vec); diff --git a/src/authenticators/unix_peer_credentials_authenticator/mod.rs b/src/authenticators/unix_peer_credentials_authenticator/mod.rs index 8e7d904c..1aea1a2e 100644 --- a/src/authenticators/unix_peer_credentials_authenticator/mod.rs +++ b/src/authenticators/unix_peer_credentials_authenticator/mod.rs @@ -9,7 +9,7 @@ //! //! Currently, the stringified UID is used as the application name. -use super::{AdminList, Application, Authenticate}; +use super::{AdminList, Application, ApplicationIdentity, Authenticate}; use crate::front::listener::ConnectionMetadata; use crate::utils::config::Admin; use log::error; @@ -89,7 +89,13 @@ impl Authenticate for UnixPeerCredentialsAuthenticator { if uid == expected_uid { let app_name = uid.to_string(); let is_admin = self.admins.is_admin(&app_name); - Ok(Application::new(app_name, is_admin)) + Ok(Application { + identity: ApplicationIdentity { + name: app_name, + authenticator_id: AuthType::UnixPeerCredentials as u8, + }, + is_admin, + }) } else { error!("Declared UID in authentication request does not match the process's UID."); Err(ResponseStatus::AuthenticationError) @@ -101,7 +107,6 @@ impl Authenticate for UnixPeerCredentialsAuthenticator { mod test { use super::super::Authenticate; use super::UnixPeerCredentialsAuthenticator; - use crate::authenticators::ApplicationName; use crate::front::domain_socket::peer_credentials; use crate::front::listener::ConnectionMetadata; use parsec_interface::requests::request::RequestAuth; @@ -134,15 +139,12 @@ mod test { pid: None, }); - let auth_name = authenticator + let application = authenticator .authenticate(&req_auth, conn_metadata) .expect("Failed to authenticate"); - assert_eq!( - auth_name.get_name(), - &ApplicationName::from_name(get_current_uid().to_string()) - ); - assert!(!auth_name.is_admin); + assert_eq!(application.identity.name, get_current_uid().to_string()); + assert!(!application.is_admin); } #[test] @@ -241,15 +243,12 @@ mod test { pid: None, }); - let auth_name = authenticator + let application = authenticator .authenticate(&req_auth, conn_metadata) .expect("Failed to authenticate"); - assert_eq!( - auth_name.get_name(), - &ApplicationName::from_name(get_current_uid().to_string()) - ); - assert!(auth_name.is_admin); + assert_eq!(application.identity.name, get_current_uid().to_string()); + assert!(application.is_admin); } #[test] diff --git a/src/back/backend_handler.rs b/src/back/backend_handler.rs index ef5317d3..d0b574e9 100644 --- a/src/back/backend_handler.rs +++ b/src/back/backend_handler.rs @@ -103,7 +103,7 @@ impl BackEndHandler { if !app.is_admin() { warn!( "Application name \"{}\" tried to perform an admin operation ({:?}).", - app.get_name(), + app.identity().name(), opcode ); return Response::from_request_header(header, ResponseStatus::AdminOperation); @@ -131,14 +131,15 @@ impl BackEndHandler { let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); let result = unwrap_or_else_return!(self .provider - .psa_generate_key(app.into(), op_generate_key)); + .psa_generate_key(app.identity(), op_generate_key)); trace!("psa_generate_key egress"); self.result_to_response(NativeResult::PsaGenerateKey(result), header) } NativeOperation::PsaImportKey(op_import_key) => { let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); - let result = - unwrap_or_else_return!(self.provider.psa_import_key(app.into(), op_import_key)); + let result = unwrap_or_else_return!(self + .provider + .psa_import_key(app.identity(), op_import_key)); trace!("psa_import_key egress"); self.result_to_response(NativeResult::PsaImportKey(result), header) } @@ -146,14 +147,15 @@ impl BackEndHandler { let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); let result = unwrap_or_else_return!(self .provider - .psa_export_public_key(app.into(), op_export_public_key)); + .psa_export_public_key(app.identity(), op_export_public_key)); trace!("psa_export_public_key egress"); self.result_to_response(NativeResult::PsaExportPublicKey(result), header) } NativeOperation::PsaExportKey(op_export_key) => { let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); - let result = - unwrap_or_else_return!(self.provider.psa_export_key(app.into(), op_export_key)); + let result = unwrap_or_else_return!(self + .provider + .psa_export_key(app.identity(), op_export_key)); trace!("psa_export_key egress"); self.result_to_response(NativeResult::PsaExportKey(result), header) } @@ -161,14 +163,15 @@ impl BackEndHandler { let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); let result = unwrap_or_else_return!(self .provider - .psa_destroy_key(app.into(), op_destroy_key)); + .psa_destroy_key(app.identity(), op_destroy_key)); trace!("psa_destroy_key egress"); self.result_to_response(NativeResult::PsaDestroyKey(result), header) } NativeOperation::PsaSignHash(op_sign_hash) => { let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); - let result = - unwrap_or_else_return!(self.provider.psa_sign_hash(app.into(), op_sign_hash)); + let result = unwrap_or_else_return!(self + .provider + .psa_sign_hash(app.identity(), op_sign_hash)); trace!("psa_sign_hash egress"); self.result_to_response(NativeResult::PsaSignHash(result), header) } @@ -176,7 +179,7 @@ impl BackEndHandler { let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); let result = unwrap_or_else_return!(self .provider - .psa_verify_hash(app.into(), op_verify_hash)); + .psa_verify_hash(app.identity(), op_verify_hash)); trace!("psa_verify_hash egress"); self.result_to_response(NativeResult::PsaVerifyHash(result), header) } @@ -184,7 +187,7 @@ impl BackEndHandler { let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); let result = unwrap_or_else_return!(self .provider - .psa_asymmetric_encrypt(app.into(), op_asymmetric_encrypt)); + .psa_asymmetric_encrypt(app.identity(), op_asymmetric_encrypt)); trace!("psa_asymmetric_encrypt egress"); self.result_to_response(NativeResult::PsaAsymmetricEncrypt(result), header) } @@ -192,7 +195,7 @@ impl BackEndHandler { let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); let result = unwrap_or_else_return!(self .provider - .psa_asymmetric_decrypt(app.into(), op_asymmetric_decrypt)); + .psa_asymmetric_decrypt(app.identity(), op_asymmetric_decrypt)); trace!("psa_asymmetric_decrypt egress"); self.result_to_response(NativeResult::PsaAsymmetricDecrypt(result), header) } @@ -200,7 +203,7 @@ impl BackEndHandler { let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); let result = unwrap_or_else_return!(self .provider - .psa_aead_encrypt(app.into(), op_aead_encrypt)); + .psa_aead_encrypt(app.identity(), op_aead_encrypt)); trace!("psa_aead_encrypt egress"); self.result_to_response(NativeResult::PsaAeadEncrypt(result), header) } @@ -208,7 +211,7 @@ impl BackEndHandler { let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); let result = unwrap_or_else_return!(self .provider - .psa_aead_decrypt(app.into(), op_aead_decrypt)); + .psa_aead_decrypt(app.identity(), op_aead_decrypt)); trace!("psa_aead_decrypt egress"); self.result_to_response(NativeResult::PsaAeadDecrypt(result), header) } @@ -222,7 +225,7 @@ impl BackEndHandler { NativeOperation::ListKeys(op_list_keys) => { let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); let result = - unwrap_or_else_return!(self.provider.list_keys(app.into(), op_list_keys)); + unwrap_or_else_return!(self.provider.list_keys(app.identity(), op_list_keys)); trace!("list_keys egress"); self.result_to_response(NativeResult::ListKeys(result), header) } @@ -232,7 +235,10 @@ impl BackEndHandler { self.result_to_response(NativeResult::ListClients(result), header) } NativeOperation::DeleteClient(op_delete_client) => { - let result = unwrap_or_else_return!(self.provider.delete_client(op_delete_client)); + let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); + let result = unwrap_or_else_return!(self + .provider + .delete_client(app.identity(), op_delete_client)); trace!("delete_client egress"); self.result_to_response(NativeResult::DeleteClient(result), header) } @@ -252,7 +258,7 @@ impl BackEndHandler { let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); let result = unwrap_or_else_return!(self .provider - .psa_raw_key_agreement(app.into(), op_raw_key_agreement)); + .psa_raw_key_agreement(app.identity(), op_raw_key_agreement)); trace!("psa_raw_key_agreement egress"); self.result_to_response(NativeResult::PsaRawKeyAgreement(result), header) } @@ -266,7 +272,7 @@ impl BackEndHandler { let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); let result = unwrap_or_else_return!(self .provider - .psa_sign_message(app.into(), op_sign_message)); + .psa_sign_message(app.identity(), op_sign_message)); trace!("psa_sign_message egress"); self.result_to_response(NativeResult::PsaSignMessage(result), header) } @@ -274,7 +280,7 @@ impl BackEndHandler { let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); let result = unwrap_or_else_return!(self .provider - .psa_verify_message(app.into(), op_verify_message)); + .psa_verify_message(app.identity(), op_verify_message)); trace!("psa_verify_message egress"); self.result_to_response(NativeResult::PsaVerifyMessage(result), header) } diff --git a/src/front/front_end.rs b/src/front/front_end.rs index 078c0ed3..05d27572 100644 --- a/src/front/front_end.rs +++ b/src/front/front_end.rs @@ -92,7 +92,7 @@ impl FrontEndHandler { if let Some(app) = &app.as_ref() { info!( "New request received from application name \"{}\"", - app.get_name() + app.identity().name() ) } else { info!("New request received without authentication") @@ -111,7 +111,7 @@ impl FrontEndHandler { if let Some(app) = app { info!( "Response for application name \"{}\" sent back", - app.get_name() + app.identity().name() ); } else { info!("Response sent back from request without authentication"); diff --git a/src/key_info_managers/mod.rs b/src/key_info_managers/mod.rs index 3471d9d1..45ad111b 100644 --- a/src/key_info_managers/mod.rs +++ b/src/key_info_managers/mod.rs @@ -6,15 +6,18 @@ //! trait to help providers to store in a persistent manner the mapping between the name and the //! information of the keys they manage. Different implementors might store this mapping using different //! means but it has to be persistent. - -use crate::authenticators::ApplicationName; +use crate::authenticators::ApplicationIdentity; +#[allow(deprecated)] +use crate::key_info_managers::on_disk_manager::KeyTriple; +use crate::providers::ProviderIdentity; use crate::utils::config::{KeyInfoManagerConfig, KeyInfoManagerType}; use anyhow::Result; use derivative::Derivative; use parsec_interface::operations::psa_key_attributes::Attributes; -use parsec_interface::requests::{ProviderId, ResponseStatus}; +use parsec_interface::requests::ResponseStatus; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; +use std::convert::TryFrom; use std::fmt; use std::sync::{Arc, RwLock}; use zeroize::Zeroize; @@ -24,18 +27,21 @@ pub mod on_disk_manager; /// This structure corresponds to a unique identifier of the key. It is used internally by the Key /// ID manager to refer to a key. #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct KeyTriple { - app_name: ApplicationName, - provider_id: ProviderId, +pub struct KeyIdentity { + /// The identity of the application that created the key. + application: ApplicationIdentity, + /// The identity of the provider where the key is stored. + provider: ProviderIdentity, + /// The key name key_name: String, } -impl fmt::Display for KeyTriple { +impl fmt::Display for KeyIdentity { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "Application Name: \"{}\", Provider ID: {}, Key Name: \"{}\"", - self.app_name, self.provider_id, self.key_name + "KeyIdentity: {{\n{},\n{},\nkey_name: \"{}\",\n}}", + self.application, self.provider, self.key_name ) } } @@ -50,29 +56,43 @@ struct KeyInfo { attributes: Attributes, } -impl KeyTriple { - /// Creates a new instance of KeyTriple. - pub fn new(app_name: ApplicationName, provider_id: ProviderId, key_name: String) -> KeyTriple { - KeyTriple { - app_name, - provider_id, +impl KeyIdentity { + /// Creates a new instance of KeyIdentity. + pub fn new( + application: ApplicationIdentity, + provider: ProviderIdentity, + key_name: String, + ) -> KeyIdentity { + KeyIdentity { + application, + provider, key_name, } } /// Checks if this key belongs to a specific provider. - pub fn belongs_to_provider(&self, provider_id: ProviderId) -> bool { - self.provider_id == provider_id + pub fn belongs_to_provider(&self, provider_name: String) -> bool { + *self.provider().name() == provider_name } /// Get the key name - pub fn key_name(&self) -> &str { + pub fn key_name(&self) -> &String { &self.key_name } + /// Get the application identity of the key + pub fn application(&self) -> &ApplicationIdentity { + &self.application + } + + /// Get the application identity of the key + pub fn provider(&self) -> &ProviderIdentity { + &self.provider + } + /// Get the app name - pub fn app_name(&self) -> &ApplicationName { - &self.app_name + pub fn app_name(&self) -> &String { + &self.application.name() } } @@ -96,14 +116,14 @@ trait ManageKeyInfo { /// # Errors /// /// Returns an error as a String if there was a problem accessing the Key Info Manager. - fn get(&self, key_triple: &KeyTriple) -> Result, String>; + fn get(&self, key_identity: &KeyIdentity) -> Result, String>; /// Returns a Vec of reference to the key triples corresponding to this provider. /// /// # Errors /// /// Returns an error as a String if there was a problem accessing the Key Info Manager. - fn get_all(&self, provider_id: ProviderId) -> Result, String>; + fn get_all(&self, provider_identity: ProviderIdentity) -> Result, String>; /// Inserts a new mapping between the key triple and the key info. If the triple already exists, /// overwrite the existing mapping and returns the old `KeyInfo`. Otherwise returns `None`. @@ -113,7 +133,7 @@ trait ManageKeyInfo { /// Returns an error as a String if there was a problem accessing the Key Info Manager. fn insert( &mut self, - key_triple: KeyTriple, + key_identity: KeyIdentity, key_info: KeyInfo, ) -> Result, String>; @@ -123,14 +143,14 @@ trait ManageKeyInfo { /// # Errors /// /// Returns an error as a String if there was a problem accessing the Key Info Manager. - fn remove(&mut self, key_triple: &KeyTriple) -> Result, String>; + fn remove(&mut self, key_identity: &KeyIdentity) -> Result, String>; /// Check if a key triple mapping exists. /// /// # Errors /// /// Returns an error as a String if there was a problem accessing the Key Info Manager. - fn exists(&self, key_triple: &KeyTriple) -> Result; + fn exists(&self, key_identity: &KeyIdentity) -> Result; } /// KeyInfoManager client structure that bridges between the KIM and the providers that need @@ -138,15 +158,19 @@ trait ManageKeyInfo { #[derive(Derivative)] #[derivative(Debug)] pub struct KeyInfoManagerClient { - provider_id: ProviderId, + provider_identity: ProviderIdentity, #[derivative(Debug = "ignore")] key_info_manager_impl: Arc>, } impl KeyInfoManagerClient { /// Get the KeyTriple representing a key. - pub fn get_key_triple(&self, app_name: ApplicationName, key_name: String) -> KeyTriple { - KeyTriple::new(app_name, self.provider_id, key_name) + pub fn get_key_triple( + &self, + application: ApplicationIdentity, + key_name: String, + ) -> KeyIdentity { + KeyIdentity::new(application, self.provider_identity.clone(), key_name) } /// Get the key ID for a given key triple @@ -161,13 +185,13 @@ impl KeyInfoManagerClient { /// type fails, InvalidEncoding is returned. pub fn get_key_id( &self, - key_triple: &KeyTriple, + key_identity: &KeyIdentity, ) -> parsec_interface::requests::Result { let key_info_manager_impl = self .key_info_manager_impl .read() .expect("Key Info Manager lock poisoned"); - let key_info = match key_info_manager_impl.get(key_triple) { + let key_info = match key_info_manager_impl.get(key_identity) { Ok(Some(key_info)) => key_info, Ok(None) => return Err(ResponseStatus::PsaErrorDoesNotExist), Err(string) => return Err(to_response_status(string)), @@ -185,7 +209,7 @@ impl KeyInfoManagerClient { /// KeyInfoManagerError is returned. pub fn get_key_attributes( &self, - key_triple: &KeyTriple, + key_triple: &KeyIdentity, ) -> parsec_interface::requests::Result { let key_info_manager_impl = self .key_info_manager_impl @@ -200,15 +224,15 @@ impl KeyInfoManagerClient { } /// Get all the key triples for the current provider - pub fn get_all(&self) -> parsec_interface::requests::Result> { + pub fn get_all(&self) -> parsec_interface::requests::Result> { let key_info_manager_impl = self .key_info_manager_impl .read() .expect("Key Info Manager lock poisoned"); key_info_manager_impl - .get_all(self.provider_id) - .map(|vec| vec.into_iter().cloned().collect()) + .get_all(self.provider_identity.clone()) + // .map(|vec| vec.into_iter().cloned().collect()) .map_err(to_response_status) } @@ -220,7 +244,7 @@ impl KeyInfoManagerClient { /// KeyInfoManagerError is returned. pub fn remove_key_info( &self, - key_triple: &KeyTriple, + key_triple: &KeyIdentity, ) -> parsec_interface::requests::Result<()> { let mut key_info_manager_impl = self .key_info_manager_impl @@ -241,7 +265,7 @@ impl KeyInfoManagerClient { /// any other error occurring in the KIM, KeyInfoManagerError is returned. pub fn insert_key_info( &self, - key_triple: KeyTriple, + key_triple: KeyIdentity, key_id: &T, attributes: Attributes, ) -> parsec_interface::requests::Result<()> { @@ -261,24 +285,25 @@ impl KeyInfoManagerClient { } } - /// Returns a Vec of ApplicationName of clients having keys in the provider. + /// Returns a Vec of ApplicationIdentity of clients having keys in the provider. /// /// # Errors /// /// Returns an error as a String if there was a problem accessing the Key Info Manager. - pub fn list_clients(&self) -> parsec_interface::requests::Result> { + pub fn list_clients(&self) -> parsec_interface::requests::Result> { let key_info_manager_impl = self .key_info_manager_impl .read() .expect("Key Info Manager lock poisoned"); - let key_triples = key_info_manager_impl - .get_all(self.provider_id) + let key_identities = key_info_manager_impl + .get_all(self.provider_identity.clone()) .map_err(to_response_status)?; - let mut clients = Vec::new(); - for key_triple in key_triples { - if !clients.contains(key_triple.app_name()) { - let _ = clients.push(key_triple.app_name().clone()); + let mut clients = Vec::new(); + for key_identity in key_identities { + // TODO: Check this comparison + if !clients.contains(&key_identity.application) { + let _ = clients.push(key_identity.application.clone()); } } @@ -293,7 +318,7 @@ impl KeyInfoManagerClient { /// Returns an error as a String if there was a problem accessing the Key Info Manager. pub fn list_keys( &self, - app_name: &ApplicationName, + application_identity: &ApplicationIdentity, ) -> parsec_interface::requests::Result> { use parsec_interface::operations::list_keys::KeyInfo; @@ -303,26 +328,33 @@ impl KeyInfoManagerClient { .expect("Key Info Manager lock poisoned"); let mut keys: Vec = Vec::new(); - let key_triples = key_info_manager_impl - .get_all(self.provider_id) + let key_identities = key_info_manager_impl + .get_all(self.provider_identity.clone()) .map_err(to_response_status)?; - for key_triple in key_triples { - if key_triple.app_name() != app_name { + for key_identity in key_identities { + // TODO: Change this to also match on authenticator_id for SQLiteKeyInfoManager. + if key_identity.application.name() != application_identity.name() { continue; } let key_info = key_info_manager_impl - .get(key_triple) + .get(&key_identity) .map_err(to_response_status)?; let key_info = match key_info { Some(key_info) => key_info, _ => continue, }; + // TODO: Fix this translation when SQLiteKeyInfoManager is added. + #[allow(deprecated)] + let key_triple = + KeyTriple::try_from(key_identity.clone()).map_err(to_response_status)?; + + #[allow(deprecated)] keys.push(KeyInfo { - provider_id: key_triple.provider_id, - name: key_triple.key_name().to_string(), + provider_id: *key_triple.provider_id(), + name: key_identity.key_name().to_string(), attributes: key_info.attributes, }); } @@ -336,7 +368,7 @@ impl KeyInfoManagerClient { /// /// Returns PsaErrorAlreadyExists if the key triple already exists or KeyInfoManagerError for /// another error. - pub fn does_not_exist(&self, key_triple: &KeyTriple) -> Result<(), ResponseStatus> { + pub fn does_not_exist(&self, key_triple: &KeyIdentity) -> Result<(), ResponseStatus> { let key_info_manager_impl = self .key_info_manager_impl .read() @@ -380,10 +412,10 @@ impl KeyInfoManagerFactory { } /// Build a KeyInfoManagerClient - pub fn build_client(&self, provider: ProviderId) -> KeyInfoManagerClient { + pub fn build_client(&self, provider_identity: ProviderIdentity) -> KeyInfoManagerClient { KeyInfoManagerClient { key_info_manager_impl: self.key_info_manager_impl.clone(), - provider_id: provider, + provider_identity, } } } diff --git a/src/key_info_managers/on_disk_manager/mod.rs b/src/key_info_managers/on_disk_manager/mod.rs index 2344bac5..c046f52c 100644 --- a/src/key_info_managers/on_disk_manager/mod.rs +++ b/src/key_info_managers/on_disk_manager/mod.rs @@ -12,26 +12,207 @@ //! example, for operating systems having a limit of 255 characters for filenames (Unix systems), //! names will be limited to 188 bytes of UTF-8 characters. //! For security reasons, only the PARSEC service should have the ability to modify these files. -use super::{KeyInfo, KeyTriple, ManageKeyInfo}; -use crate::authenticators::ApplicationName; +use crate::authenticators::{Application, ApplicationIdentity}; + +use super::{KeyIdentity, KeyInfo, ManageKeyInfo, ProviderIdentity}; +use crate::providers::core::Provider as CoreProvider; +#[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 anyhow::{Context, Result}; use log::{error, info, warn}; use parsec_interface::requests::ProviderId; use std::collections::HashMap; use std::convert::TryFrom; use std::ffi::OsStr; -use std::fs; use std::fs::{DirEntry, File}; use std::io::{Error, ErrorKind, Read, Write}; +use std::ops::Deref; use std::path::{Path, PathBuf}; +use std::{fmt, fs}; /// Default path where the mapping files will be stored on disk pub const DEFAULT_MAPPINGS_PATH: &str = "/var/lib/parsec/mappings"; +/// String wrapper for app names +#[deprecated(since = "0.9.0", note = "ApplicationIdentity should be used instead.")] +#[derive(Debug, Clone, Eq, PartialEq, Hash)] +pub struct ApplicationName { + name: String, +} + +#[allow(deprecated)] +impl Deref for ApplicationName { + type Target = String; + + fn deref(&self) -> &Self::Target { + &self.name + } +} + +#[allow(deprecated)] +#[deprecated(since = "0.9.0", note = "ApplicationIdentity should be used instead.")] +impl ApplicationName { + /// Create ApplicationName from name string only + pub fn from_name(name: String) -> ApplicationName { + ApplicationName { name } + } +} + +#[allow(deprecated)] +impl std::fmt::Display for ApplicationName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.name) + } +} + +#[allow(deprecated)] +impl From for ApplicationName { + fn from(app: Application) -> Self { + ApplicationName::from_name(app.identity().name().clone()) + } +} + +/// Should only be used internally to map KeyTriple to the new KeyIdentity +/// for the on_disk_manager KeyInfoManager. +/// Structure corresponds to a unique identifier of the key. +/// It is used internally by the Key ID manager to refer to a key. +#[deprecated(since = "0.9.0", note = "KeyIdentity should be used instead.")] +#[allow(deprecated)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct KeyTriple { + app_name: ApplicationName, + provider_id: ProviderId, + key_name: String, +} + +#[allow(deprecated)] +#[deprecated(since = "0.9.0", note = "KeyIdentity should be used instead.")] +impl KeyTriple { + /// Creates a new instance of KeyTriple. + pub fn new(app_name: ApplicationName, provider_id: ProviderId, key_name: String) -> KeyTriple { + KeyTriple { + app_name, + provider_id, + key_name, + } + } + + /// Checks if this key belongs to a specific provider. + pub fn belongs_to_provider(&self, provider_id: ProviderId) -> bool { + self.provider_id == provider_id + } + /// Get the provider id + pub fn provider_id(&self) -> &ProviderId { + &self.provider_id + } + + /// Get the key name + pub fn key_name(&self) -> &str { + &self.key_name + } + + /// Get the app name + pub fn app_name(&self) -> &ApplicationName { + &self.app_name + } +} + +#[allow(deprecated)] +impl fmt::Display for KeyTriple { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "KeyTriple: app_name=\"{}\" provider_id={} key_name=\"{}\"", + self.app_name, self.provider_id, self.key_name + ) + } +} + +#[allow(deprecated)] +impl TryFrom for KeyTriple { + type Error = String; + + fn try_from(key_identity: KeyIdentity) -> ::std::result::Result { + let provider_id = match key_identity.provider.uuid().as_str() { + CoreProvider::PROVIDER_UUID => Ok(ProviderId::Core), + #[cfg(feature = "cryptoauthlib-provider")] + CryptoAuthLibProvider::PROVIDER_UUID => Ok(ProviderId::CryptoAuthLib), + #[cfg(feature = "mbed-crypto-provider")] + MbedCryptoProvider::PROVIDER_UUID => Ok(ProviderId::MbedCrypto), + #[cfg(feature = "pkcs11-provider")] + Pkcs11Provider::PROVIDER_UUID => Ok(ProviderId::Pkcs11), + #[cfg(feature = "tpm-provider")] + TpmProvider::PROVIDER_UUID => Ok(ProviderId::Tpm), + #[cfg(feature = "trusted-service-provider")] + TrustedServiceProvider::PROVIDER_UUID => Ok(ProviderId::TrustedService), + _ => Err(format!( + "Cannot convert from KeyIdentity to KeyTriple. + Provider \"{}\" is not recognised. + Could be it does not exist, or Parsec was not compiled with the required provider feature flags.", + key_identity.provider().uuid() + )), + }?; + + let app_name = ApplicationName::from_name(key_identity.application().name().clone()); + Ok(KeyTriple { + provider_id, + app_name, + key_name: key_identity.key_name, + }) + } +} + +#[allow(deprecated)] +impl TryFrom for KeyIdentity { + type Error = String; + + fn try_from(key_triple: KeyTriple) -> ::std::result::Result { + // Result types required by clippy as Err result has the possibility of not being compiled. + let provider_uuid = match key_triple.provider_id { + ProviderId::Core => Ok::( + CoreProvider::PROVIDER_UUID.to_string(), + ), + #[cfg(feature = "cryptoauthlib-provider")] + ProviderId::CryptoAuthLib => Ok::(CryptoAuthLibProvider::PROVIDER_UUID.to_string()), + #[cfg(feature = "mbed-crypto-provider")] + ProviderId::MbedCrypto => Ok::(MbedCryptoProvider::PROVIDER_UUID.to_string()), + #[cfg(feature = "pkcs11-provider")] + ProviderId::Pkcs11 => Ok::(Pkcs11Provider::PROVIDER_UUID.to_string()), + #[cfg(feature = "tpm-provider")] + ProviderId::Tpm => Ok::(TpmProvider::PROVIDER_UUID.to_string()), + #[cfg(feature = "trusted-service-provider")] + ProviderId::TrustedService => Ok::(TrustedServiceProvider::PROVIDER_UUID.to_string()), + #[cfg(not(all( + feature = "cryptoauthlib-provider", + feature = "mbed-crypto-provider", + feature = "pkcs11-provider", + feature = "tpm-provider", + feature = "trusted-service-provider", + )))] + _ => 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)), + }?; + + Ok(KeyIdentity { + provider: ProviderIdentity::new(provider_uuid, String::from("")), // TODO: Figure out a better default null name + application: ApplicationIdentity::new(key_triple.app_name().to_string(), 0xFF), // TODO: Figure out a better default null authenticator_id + key_name: key_triple.key_name.to_string(), + }) + } +} + /// A key info manager storing key triple to key info mapping on files on disk #[derive(Debug)] pub struct OnDiskKeyInfoManager { /// Internal mapping, used for non-modifying operations. + #[allow(deprecated)] key_store: HashMap, /// Folder where all the key triple to key info mappings are saved. This folder will be created /// if it does already exist. @@ -41,6 +222,7 @@ pub struct OnDiskKeyInfoManager { /// Encodes a KeyTriple's data into base64 strings that can be used as filenames. /// The ProviderId will not be converted as a base64 as it can always be represented as a String /// being a number from 0 and 255. +#[allow(deprecated)] fn key_triple_to_base64_filenames(key_triple: &KeyTriple) -> (String, String, String) { ( base64::encode_config(key_triple.app_name.as_bytes(), base64::URL_SAFE), @@ -70,6 +252,7 @@ fn base64_data_to_string(base64_bytes: &[u8]) -> Result { /// # Errors /// /// Returns an error as a string if either the decoding or the bytes conversion to UTF-8 failed. +#[allow(deprecated)] fn base64_data_triple_to_key_triple( app_name: &[u8], provider_id: ProviderId, @@ -152,6 +335,7 @@ fn list_files(path: &Path) -> std::io::Result> { /// /// The `OnDiskKeyInfoManager` relies on access control mechanisms provided by the OS for /// the filesystem to ensure security of the mappings. +#[allow(deprecated)] impl OnDiskKeyInfoManager { /// Creates an instance of the on-disk manager from the mapping files. This function will /// create the mappings directory if it does not already exist. @@ -302,30 +486,40 @@ impl OnDiskKeyInfoManager { } } +#[allow(deprecated)] impl ManageKeyInfo for OnDiskKeyInfoManager { - fn get(&self, key_triple: &KeyTriple) -> Result, String> { + fn get(&self, key_identity: &KeyIdentity) -> Result, String> { + let key_triple = KeyTriple::try_from(key_identity.clone())?; // An Option<&Vec> can not automatically coerce to an Option<&[u8]>, it needs to be // done by hand. - if let Some(key_info) = self.key_store.get(key_triple) { + if let Some(key_info) = self.key_store.get(&key_triple) { Ok(Some(key_info)) } else { Ok(None) } } - fn get_all(&self, provider_id: ProviderId) -> Result, String> { - Ok(self + fn get_all(&self, provider_identity: ProviderIdentity) -> Result, String> { + let provider_id = ProviderId::try_from(provider_identity)?; + let key_triples = self .key_store .keys() - .filter(|key_triple| key_triple.belongs_to_provider(provider_id)) - .collect()) + .filter(|key_triple| key_triple.belongs_to_provider(provider_id)); + + let mut key_identites = Vec::new(); + for key_triple in key_triples { + let key_identity = KeyIdentity::try_from(key_triple.clone())?; + key_identites.push(key_identity) + } + Ok(key_identites) } fn insert( &mut self, - key_triple: KeyTriple, + key_identity: KeyIdentity, key_info: KeyInfo, ) -> Result, String> { + let key_triple = KeyTriple::try_from(key_identity)?; if let Err(err) = self.save_mapping(&key_triple, &key_info) { Err(err.to_string()) } else { @@ -333,18 +527,20 @@ impl ManageKeyInfo for OnDiskKeyInfoManager { } } - fn remove(&mut self, key_triple: &KeyTriple) -> Result, String> { - if let Err(err) = self.delete_mapping(key_triple) { + fn remove(&mut self, key_identity: &KeyIdentity) -> Result, String> { + let key_triple = KeyTriple::try_from(key_identity.clone())?; + if let Err(err) = self.delete_mapping(&key_triple) { Err(err.to_string()) - } else if let Some(key_info) = self.key_store.remove(key_triple) { + } else if let Some(key_info) = self.key_store.remove(&key_triple) { Ok(Some(key_info)) } else { Ok(None) } } - fn exists(&self, key_triple: &KeyTriple) -> Result { - Ok(self.key_store.contains_key(key_triple)) + fn exists(&self, key_identity: &KeyIdentity) -> Result { + let key_triple = KeyTriple::try_from(key_identity.clone())?; + Ok(self.key_store.contains_key(&key_triple)) } } @@ -380,16 +576,19 @@ impl OnDiskKeyInfoManagerBuilder { #[cfg(test)] mod test { - use super::super::{KeyInfo, KeyTriple, ManageKeyInfo}; + use super::super::{KeyIdentity, KeyInfo, ManageKeyInfo}; use super::OnDiskKeyInfoManager; - use crate::authenticators::ApplicationName; + use crate::key_info_managers::{ApplicationIdentity, ProviderIdentity}; + use crate::providers::core::Provider as CoreProvider; + #[cfg(feature = "mbed-crypto-provider")] + use crate::providers::mbed_crypto::Provider as MbedCryptoProvider; use parsec_interface::operations::psa_algorithm::{ Algorithm, AsymmetricSignature, Hash, SignHash, }; use parsec_interface::operations::psa_key_attributes::{ Attributes, Lifetime, Policy, Type, UsageFlags, }; - use parsec_interface::requests::ProviderId; + use parsec_interface::requests::AuthType; use std::fs; use std::path::PathBuf; @@ -528,10 +727,17 @@ mod test { let path = PathBuf::from(env!("OUT_DIR").to_owned() + "/big_names_ascii_mappings"); let mut manager = OnDiskKeyInfoManager::new(path.clone()).unwrap(); - let big_app_name_ascii = ApplicationName::from_name(" 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()); + 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(); 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(); - let key_triple = KeyTriple::new(big_app_name_ascii, ProviderId::Core, big_key_name_ascii); + let key_triple = KeyIdentity::new( + ApplicationIdentity::new(big_app_name_ascii, AuthType::NoAuth as u8), + ProviderIdentity::new( + CoreProvider::PROVIDER_UUID.to_string(), + CoreProvider::DEFAULT_PROVIDER_NAME.to_string(), + ), + big_key_name_ascii, + ); let key_info = test_key_info(); let _ = manager @@ -546,43 +752,68 @@ mod test { let path = PathBuf::from(env!("OUT_DIR").to_owned() + "/big_names_emoticons_mappings"); let mut manager = OnDiskKeyInfoManager::new(path.clone()).unwrap(); - let big_app_name_emoticons = ApplicationName::from_name("😀😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐😑😒😓😔😕😖😗😘😙😚😛😜😝😞😟😠😡😢😣😤😥😦😧😨😩😪😫😬😭😮".to_string()); + let big_app_name_emoticons = "😀😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐😑😒😓😔😕😖😗😘😙😚😛😜😝😞😟😠😡😢😣😤😥😦😧😨😩😪😫😬😭😮".to_string(); let big_key_name_emoticons = "😀😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐😑😒😓😔😕😖😗😘😙😚😛😜😝😞😟😠😡😢😣😤😥😦😧😨😩😪😫😬😭😮".to_string(); - let key_triple = KeyTriple::new( - big_app_name_emoticons, - ProviderId::MbedCrypto, + let key_identity = KeyIdentity::new( + ApplicationIdentity::new(big_app_name_emoticons, AuthType::NoAuth as u8), + ProviderIdentity::new( + CoreProvider::PROVIDER_UUID.to_string(), + CoreProvider::DEFAULT_PROVIDER_NAME.to_string(), + ), big_key_name_emoticons, ); let key_info = test_key_info(); let _ = manager - .insert(key_triple.clone(), key_info.clone()) + .insert(key_identity.clone(), key_info.clone()) .unwrap(); - assert_eq!(manager.remove(&key_triple).unwrap().unwrap(), key_info); + assert_eq!(manager.remove(&key_identity).unwrap().unwrap(), key_info); fs::remove_dir_all(path).unwrap(); } + #[cfg(feature = "mbed-crypto-provider")] #[test] fn create_and_load() { let path = PathBuf::from(env!("OUT_DIR").to_owned() + "/create_and_load_mappings"); - let app_name1 = ApplicationName::from_name("😀 Application One 😀".to_string()); + let app_name1 = "😀 Application One 😀".to_string(); let key_name1 = "😀 Key One 😀".to_string(); - let key_triple1 = KeyTriple::new(app_name1, ProviderId::Core, key_name1); + let key_identity_1 = KeyIdentity::new( + ApplicationIdentity::new(app_name1, AuthType::NoAuth as u8), + ProviderIdentity::new( + CoreProvider::PROVIDER_UUID.to_string(), + CoreProvider::DEFAULT_PROVIDER_NAME.to_string(), + ), + key_name1, + ); let key_info1 = test_key_info(); - let app_name2 = ApplicationName::from_name("😇 Application Two 😇".to_string()); + let app_name2 = "😇 Application Two 😇".to_string(); let key_name2 = "😇 Key Two 😇".to_string(); - let key_triple2 = KeyTriple::new(app_name2, ProviderId::MbedCrypto, key_name2); + let key_identity_2 = KeyIdentity::new( + ApplicationIdentity::new(app_name2, AuthType::NoAuth as u8), + ProviderIdentity::new( + MbedCryptoProvider::PROVIDER_UUID.to_string(), + MbedCryptoProvider::DEFAULT_PROVIDER_NAME.to_string(), + ), + key_name2, + ); let key_info2 = KeyInfo { id: vec![0x12, 0x22, 0x32], attributes: test_key_attributes(), }; - let app_name3 = ApplicationName::from_name("😈 Application Three 😈".to_string()); + let app_name3 = "😈 Application Three 😈".to_string(); let key_name3 = "😈 Key Three 😈".to_string(); - let key_triple3 = KeyTriple::new(app_name3, ProviderId::Core, key_name3); + let key_identity_3 = KeyIdentity::new( + ApplicationIdentity::new(app_name3, AuthType::NoAuth as u8), + ProviderIdentity::new( + CoreProvider::PROVIDER_UUID.to_string(), + CoreProvider::DEFAULT_PROVIDER_NAME.to_string(), + ), + key_name3, + ); let key_info3 = KeyInfo { id: vec![0x13, 0x23, 0x33], attributes: test_key_attributes(), @@ -591,31 +822,34 @@ mod test { let mut manager = OnDiskKeyInfoManager::new(path.clone()).unwrap(); let _ = manager - .insert(key_triple1.clone(), key_info1.clone()) + .insert(key_identity_1.clone(), key_info1.clone()) .unwrap(); let _ = manager - .insert(key_triple2.clone(), key_info2.clone()) + .insert(key_identity_2.clone(), key_info2.clone()) .unwrap(); let _ = manager - .insert(key_triple3.clone(), key_info3.clone()) + .insert(key_identity_3.clone(), key_info3.clone()) .unwrap(); } // The local hashmap is dropped when leaving the inner scope. { let mut manager = OnDiskKeyInfoManager::new(path.clone()).unwrap(); - assert_eq!(manager.remove(&key_triple1).unwrap().unwrap(), key_info1); - assert_eq!(manager.remove(&key_triple2).unwrap().unwrap(), key_info2); - assert_eq!(manager.remove(&key_triple3).unwrap().unwrap(), key_info3); + assert_eq!(manager.remove(&key_identity_1).unwrap().unwrap(), key_info1); + assert_eq!(manager.remove(&key_identity_2).unwrap().unwrap(), key_info2); + assert_eq!(manager.remove(&key_identity_3).unwrap().unwrap(), key_info3); } fs::remove_dir_all(path).unwrap(); } - fn new_key_triple(key_name: String) -> KeyTriple { - KeyTriple::new( - ApplicationName::from_name("Testing Application 😎".to_string()), - ProviderId::MbedCrypto, + fn new_key_triple(key_name: String) -> KeyIdentity { + KeyIdentity::new( + ApplicationIdentity::new("Testing Application 😎".to_string(), AuthType::NoAuth as u8), + ProviderIdentity::new( + CoreProvider::PROVIDER_UUID.to_string(), + CoreProvider::DEFAULT_PROVIDER_NAME.to_string(), + ), key_name, ) } diff --git a/src/providers/core/mod.rs b/src/providers/core/mod.rs index 8b052629..ede0bc1d 100644 --- a/src/providers/core/mod.rs +++ b/src/providers/core/mod.rs @@ -6,7 +6,7 @@ //! aiding clients in discovering the capabilities offered by their underlying //! platform. use super::Provide; -use crate::authenticators::ApplicationName; +use crate::authenticators::ApplicationIdentity; use derivative::Derivative; use log::{error, trace}; use parsec_interface::operations::{ @@ -49,6 +49,14 @@ pub struct Provider { prov_list: Vec>, } +impl Provider { + /// The default provider name for cryptoauthlib provider + pub const DEFAULT_PROVIDER_NAME: &'static str = "core-provider"; + + /// The UUID for this provider + pub const PROVIDER_UUID: &'static str = "47049873-2a43-4845-9d72-831eab668784"; +} + impl Provide for Provider { fn list_opcodes(&self, op: list_opcodes::Operation) -> Result { trace!("list_opcodes ingress"); @@ -80,7 +88,7 @@ impl Provide for Provider { fn list_keys( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, _op: list_keys::Operation, ) -> Result { trace!("list_keys ingress"); @@ -93,7 +101,7 @@ impl Provide for Provider { "unknown".to_string() }; let mut result = provider - .list_keys(app_name.clone(), _op) + .list_keys(application_identity, _op) .unwrap_or_else(|e| { error!("list_keys failed on provider {} with {}", id, e); list_keys::Result { keys: Vec::new() } @@ -128,7 +136,11 @@ impl Provide for Provider { Ok(list_clients::Result { clients }) } - fn delete_client(&self, op: delete_client::Operation) -> Result { + fn delete_client( + &self, + application_identity: &ApplicationIdentity, + op: delete_client::Operation, + ) -> Result { trace!("delete_client ingress"); let client = op.client; @@ -142,7 +154,10 @@ impl Provide for Provider { // Currently Parsec only stores keys, we delete all of them. let keys = provider .list_keys( - ApplicationName::from_name(client.clone()), + &ApplicationIdentity::new( + client.clone(), + *application_identity.authenticator_id(), + ), list_keys::Operation {}, ) .unwrap_or_else(|e| { @@ -154,7 +169,8 @@ impl Provide for Provider { let key_name = key.name; let _ = provider .psa_destroy_key( - ApplicationName::from_name(client.clone()), + // TODO: Check auth type. Will need passing down when SQLite KIM is implemented. + &ApplicationIdentity::new(client.clone(), 0xFE), psa_destroy_key::Operation { key_name }, ) .unwrap_or_else(|e| { diff --git a/src/providers/cryptoauthlib/asym_sign.rs b/src/providers/cryptoauthlib/asym_sign.rs index a974764b..9fc749b7 100644 --- a/src/providers/cryptoauthlib/asym_sign.rs +++ b/src/providers/cryptoauthlib/asym_sign.rs @@ -1,15 +1,15 @@ // Copyright 2021 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 use super::Provider; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::KeyTriple; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::KeyIdentity; use log::error; use parsec_interface::operations::psa_algorithm::{AsymmetricSignature, Hash, SignHash}; use parsec_interface::operations::psa_key_attributes::{EccFamily, Type}; use parsec_interface::operations::{ psa_sign_hash, psa_sign_message, psa_verify_hash, psa_verify_message, }; -use parsec_interface::requests::{ProviderId, ResponseStatus, Result}; +use parsec_interface::requests::{ResponseStatus, Result}; use rust_cryptoauthlib::AtcaStatus; impl Provider { @@ -76,10 +76,14 @@ impl Provider { pub(super) fn psa_sign_hash_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_sign_hash::Operation, ) -> Result { - let key_triple = KeyTriple::new(app_name, ProviderId::CryptoAuthLib, op.key_name.clone()); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + op.key_name.clone(), + ); let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; op.validate(key_attributes)?; @@ -100,12 +104,12 @@ impl Provider { pub(super) fn psa_verify_hash_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_verify_hash::Operation, ) -> Result { let key_triple = self .key_info_store - .get_key_triple(app_name, op.key_name.clone()); + .get_key_triple(application_identity.clone(), op.key_name.clone()); let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; op.validate(key_attributes)?; @@ -127,12 +131,12 @@ impl Provider { pub(super) fn psa_sign_message_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_sign_message::Operation, ) -> Result { let key_triple = self .key_info_store - .get_key_triple(app_name, op.key_name.clone()); + .get_key_triple(application_identity.clone(), op.key_name.clone()); let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; op.validate(key_attributes)?; @@ -155,12 +159,12 @@ impl Provider { pub(super) fn psa_verify_message_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_verify_message::Operation, ) -> Result { let key_triple = self .key_info_store - .get_key_triple(app_name, op.key_name.clone()); + .get_key_triple(application_identity.clone(), op.key_name.clone()); let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; op.validate(key_attributes)?; diff --git a/src/providers/cryptoauthlib/key_management.rs b/src/providers/cryptoauthlib/key_management.rs index 4c2c3c47..9c3e303a 100644 --- a/src/providers/cryptoauthlib/key_management.rs +++ b/src/providers/cryptoauthlib/key_management.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use super::key_slot::KeySlotStatus; use super::Provider; -use crate::authenticators::ApplicationName; +use crate::authenticators::ApplicationIdentity; use log::{error, warn}; use parsec_interface::operations::psa_key_attributes::{Attributes, EccFamily, Type}; use parsec_interface::operations::{ @@ -15,11 +15,13 @@ use zeroize::Zeroizing; impl Provider { pub(super) fn psa_generate_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_generate_key::Operation, ) -> Result { let key_name = op.key_name; - let key_triple = self.key_info_store.get_key_triple(app_name, key_name); + let key_triple = self + .key_info_store + .get_key_triple(application_identity.clone(), key_name); self.key_info_store.does_not_exist(&key_triple)?; @@ -75,11 +77,13 @@ impl Provider { pub(super) fn psa_destroy_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_destroy_key::Operation, ) -> Result { let key_name = op.key_name; - let key_triple = self.key_info_store.get_key_triple(app_name, key_name); + let key_triple = self + .key_info_store + .get_key_triple(application_identity.clone(), key_name); let key_id = self.key_info_store.get_key_id::(&key_triple)?; match self.key_info_store.remove_key_info(&key_triple) { @@ -104,11 +108,13 @@ impl Provider { pub(super) fn psa_import_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_import_key::Operation, ) -> Result { let key_name = op.key_name; - let key_triple = self.key_info_store.get_key_triple(app_name, key_name); + let key_triple = self + .key_info_store + .get_key_triple(application_identity.clone(), key_name); self.key_info_store.does_not_exist(&key_triple)?; let key_attributes = op.attributes; @@ -172,10 +178,12 @@ impl Provider { pub(super) fn psa_export_public_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_public_key::Operation, ) -> Result { - let key_triple = self.key_info_store.get_key_triple(app_name, op.key_name); + let key_triple = self + .key_info_store + .get_key_triple(application_identity.clone(), op.key_name); let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; match key_attributes.key_type { @@ -208,10 +216,12 @@ impl Provider { pub(super) fn psa_export_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_key::Operation, ) -> Result { - let key_triple = self.key_info_store.get_key_triple(app_name, op.key_name); + let key_triple = self + .key_info_store + .get_key_triple(application_identity.clone(), op.key_name); let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; if !key_attributes.is_exportable() { diff --git a/src/providers/cryptoauthlib/mod.rs b/src/providers/cryptoauthlib/mod.rs index bd6f91c6..44ad56ad 100644 --- a/src/providers/cryptoauthlib/mod.rs +++ b/src/providers/cryptoauthlib/mod.rs @@ -5,9 +5,10 @@ //! This provider implements Parsec operations using CryptoAuthentication //! Library backed by the ATECCx08 cryptochip. use super::Provide; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::{KeyInfoManagerClient, KeyTriple}; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::{KeyIdentity, KeyInfoManagerClient}; use crate::providers::cryptoauthlib::key_slot_storage::KeySlotStorage; +use crate::providers::ProviderIdentity; use derivative::Derivative; use log::{error, trace, warn}; use parsec_interface::operations::list_providers::ProviderInfo; @@ -38,8 +39,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, + // The identity of the provider including uuid & name. + provider_identity: ProviderIdentity, #[derivative(Debug = "ignore")] key_info_store: KeyInfoManagerClient, key_slots: KeySlotStorage, @@ -81,7 +82,10 @@ impl Provider { cryptoauthlib_provider = Provider { device, provider_id: ProviderId::CryptoAuthLib, - provider_name, + provider_identity: ProviderIdentity { + name: provider_name, + uuid: String::from(Self::PROVIDER_UUID), + }, key_info_store, key_slots: KeySlotStorage::new(), supported_opcodes: HashSet::new(), @@ -109,7 +113,7 @@ impl Provider { // Validate key info store against hardware configuration. // Delete invalid entries or invalid mappings. // Mark the slots free/busy appropriately. - let mut to_remove: Vec = Vec::new(); + let mut to_remove: Vec = Vec::new(); match cryptoauthlib_provider.key_info_store.get_all() { Ok(key_triples) => { for key_triple in key_triples.iter().cloned() { @@ -250,11 +254,11 @@ impl Provide for Provider { fn list_keys( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, _op: list_keys::Operation, ) -> Result { Ok(list_keys::Result { - keys: self.key_info_store.list_keys(&app_name)?, + keys: self.key_info_store.list_keys(application_identity)?, }) } @@ -264,7 +268,7 @@ impl Provide for Provider { .key_info_store .list_clients()? .into_iter() - .map(|app_name| app_name.to_string()) + .map(|application_identity| application_identity.name().clone()) .collect(), }) } @@ -307,118 +311,118 @@ impl Provide for Provider { fn psa_generate_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_generate_key::Operation, ) -> Result { trace!("psa_generate_key ingress"); if !self.supported_opcodes.contains(&Opcode::PsaGenerateKey) { Err(ResponseStatus::PsaErrorNotSupported) } else { - self.psa_generate_key_internal(app_name, op) + self.psa_generate_key_internal(application_identity, op) } } fn psa_destroy_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_destroy_key::Operation, ) -> Result { trace!("psa_destroy_key ingress"); if !self.supported_opcodes.contains(&Opcode::PsaDestroyKey) { Err(ResponseStatus::PsaErrorNotSupported) } else { - self.psa_destroy_key_internal(app_name, op) + self.psa_destroy_key_internal(application_identity, op) } } fn psa_import_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_import_key::Operation, ) -> Result { trace!("psa_import_key ingress"); if !self.supported_opcodes.contains(&Opcode::PsaImportKey) { Err(ResponseStatus::PsaErrorNotSupported) } else { - self.psa_import_key_internal(app_name, op) + self.psa_import_key_internal(application_identity, op) } } fn psa_sign_hash( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_sign_hash::Operation, ) -> Result { trace!("psa_sign_hash ingress"); if !self.supported_opcodes.contains(&Opcode::PsaSignHash) { Err(ResponseStatus::PsaErrorNotSupported) } else { - self.psa_sign_hash_internal(app_name, op) + self.psa_sign_hash_internal(application_identity, op) } } fn psa_verify_hash( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_verify_hash::Operation, ) -> Result { trace!("psa_verify_hash ingress"); if !self.supported_opcodes.contains(&Opcode::PsaVerifyHash) { Err(ResponseStatus::PsaErrorNotSupported) } else { - self.psa_verify_hash_internal(app_name, op) + self.psa_verify_hash_internal(application_identity, op) } } fn psa_sign_message( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_sign_message::Operation, ) -> Result { trace!("psa_sign_message ingress"); if !self.supported_opcodes.contains(&Opcode::PsaSignMessage) { Err(ResponseStatus::PsaErrorNotSupported) } else { - self.psa_sign_message_internal(app_name, op) + self.psa_sign_message_internal(application_identity, op) } } fn psa_verify_message( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_verify_message::Operation, ) -> Result { trace!("psa_verify_message ingress"); if !self.supported_opcodes.contains(&Opcode::PsaVerifyMessage) { Err(ResponseStatus::PsaErrorNotSupported) } else { - self.psa_verify_message_internal(app_name, op) + self.psa_verify_message_internal(application_identity, op) } } fn psa_export_public_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_public_key::Operation, ) -> Result { trace!("psa_export_public_key ingress"); if !self.supported_opcodes.contains(&Opcode::PsaExportPublicKey) { Err(ResponseStatus::PsaErrorNotSupported) } else { - self.psa_export_public_key_internal(app_name, op) + self.psa_export_public_key_internal(application_identity, op) } } fn psa_export_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_key::Operation, ) -> Result { trace!("psa_export_key ingress"); if !self.supported_opcodes.contains(&Opcode::PsaExportKey) { Err(ResponseStatus::PsaErrorNotSupported) } else { - self.psa_export_key_internal(app_name, op) + self.psa_export_key_internal(application_identity, op) } } } diff --git a/src/providers/mbed_crypto/aead.rs b/src/providers/mbed_crypto/aead.rs index 825427ef..cd60cde5 100644 --- a/src/providers/mbed_crypto/aead.rs +++ b/src/providers/mbed_crypto/aead.rs @@ -1,22 +1,26 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 use super::Provider; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::KeyTriple; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::KeyIdentity; use parsec_interface::operations::{psa_aead_decrypt, psa_aead_encrypt}; -use parsec_interface::requests::{ProviderId, ResponseStatus, Result}; +use parsec_interface::requests::{ResponseStatus, Result}; use psa_crypto::operations::aead; use psa_crypto::types::key; impl Provider { pub(super) fn psa_aead_encrypt_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_aead_encrypt::Operation, ) -> Result { let key_name = op.key_name.clone(); - let key_triple = KeyTriple::new(app_name, ProviderId::MbedCrypto, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let _guard = self .key_handle_mutex @@ -54,10 +58,14 @@ impl Provider { pub(super) fn psa_aead_decrypt_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_aead_decrypt::Operation, ) -> Result { - let key_triple = KeyTriple::new(app_name, ProviderId::MbedCrypto, op.key_name.clone()); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + op.key_name.clone(), + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let _guard = self diff --git a/src/providers/mbed_crypto/asym_encryption.rs b/src/providers/mbed_crypto/asym_encryption.rs index d7a6e17f..4a87278e 100644 --- a/src/providers/mbed_crypto/asym_encryption.rs +++ b/src/providers/mbed_crypto/asym_encryption.rs @@ -1,22 +1,26 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 use super::Provider; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::KeyTriple; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::KeyIdentity; use parsec_interface::operations::{psa_asymmetric_decrypt, psa_asymmetric_encrypt}; -use parsec_interface::requests::{ProviderId, ResponseStatus, Result}; +use parsec_interface::requests::{ResponseStatus, Result}; use psa_crypto::operations::asym_encryption; use psa_crypto::types::key; impl Provider { pub(super) fn psa_asymmetric_encrypt_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_asymmetric_encrypt::Operation, ) -> Result { let key_name = op.key_name.clone(); - let key_triple = KeyTriple::new(app_name, ProviderId::MbedCrypto, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let _guard = self .key_handle_mutex @@ -48,10 +52,14 @@ impl Provider { pub(super) fn psa_asymmetric_decrypt_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_asymmetric_decrypt::Operation, ) -> Result { - let key_triple = KeyTriple::new(app_name, ProviderId::MbedCrypto, op.key_name.clone()); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + op.key_name.clone(), + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let _guard = self diff --git a/src/providers/mbed_crypto/asym_sign.rs b/src/providers/mbed_crypto/asym_sign.rs index 53222e73..c26f12d3 100644 --- a/src/providers/mbed_crypto/asym_sign.rs +++ b/src/providers/mbed_crypto/asym_sign.rs @@ -1,23 +1,27 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 use super::Provider; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::KeyTriple; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::KeyIdentity; use parsec_interface::operations::{psa_sign_hash, psa_verify_hash}; -use parsec_interface::requests::{ProviderId, ResponseStatus, Result}; +use parsec_interface::requests::{ResponseStatus, Result}; use psa_crypto::operations::asym_signature; use psa_crypto::types::key; impl Provider { pub(super) fn psa_sign_hash_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_sign_hash::Operation, ) -> Result { let key_name = op.key_name; let hash = op.hash; let alg = op.alg; - let key_triple = KeyTriple::new(app_name, ProviderId::MbedCrypto, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let _guard = self @@ -47,14 +51,18 @@ impl Provider { pub(super) fn psa_verify_hash_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_verify_hash::Operation, ) -> Result { let key_name = op.key_name; let hash = op.hash; let alg = op.alg; let signature = op.signature; - let key_triple = KeyTriple::new(app_name, ProviderId::MbedCrypto, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let _guard = self diff --git a/src/providers/mbed_crypto/key_agreement.rs b/src/providers/mbed_crypto/key_agreement.rs index 5f3cb3bb..783813b8 100644 --- a/src/providers/mbed_crypto/key_agreement.rs +++ b/src/providers/mbed_crypto/key_agreement.rs @@ -1,10 +1,10 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 use super::Provider; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::KeyTriple; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::KeyIdentity; use parsec_interface::operations::psa_raw_key_agreement; -use parsec_interface::requests::{ProviderId, ResponseStatus, Result}; +use parsec_interface::requests::{ResponseStatus, Result}; use parsec_interface::secrecy::Secret; use psa_crypto::operations::key_agreement; use psa_crypto::types::key; @@ -12,12 +12,16 @@ use psa_crypto::types::key; impl Provider { pub(super) fn psa_raw_key_agreement( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_raw_key_agreement::Operation, ) -> Result { let key_name = op.private_key_name.clone(); - let key_triple = KeyTriple::new(app_name, ProviderId::MbedCrypto, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let _guard = self .key_handle_mutex diff --git a/src/providers/mbed_crypto/key_management.rs b/src/providers/mbed_crypto/key_management.rs index 31b45b9d..2222a077 100644 --- a/src/providers/mbed_crypto/key_management.rs +++ b/src/providers/mbed_crypto/key_management.rs @@ -1,13 +1,13 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 use super::Provider; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::KeyTriple; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::KeyIdentity; use log::error; use parsec_interface::operations::{ psa_destroy_key, psa_export_key, psa_export_public_key, psa_generate_key, psa_import_key, }; -use parsec_interface::requests::{ProviderId, ResponseStatus, Result}; +use parsec_interface::requests::{ResponseStatus, Result}; use parsec_interface::secrecy::{ExposeSecret, Secret}; use psa_crypto::operations::key_management as psa_crypto_key_management; use psa_crypto::types::key; @@ -34,12 +34,16 @@ pub fn create_key_id(max_current_id: &AtomicU32) -> Result { impl Provider { pub(super) fn psa_generate_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_generate_key::Operation, ) -> Result { let key_name = op.key_name; let key_attributes = op.attributes; - let key_triple = KeyTriple::new(app_name, ProviderId::MbedCrypto, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); self.key_info_store.does_not_exist(&key_triple)?; @@ -75,13 +79,17 @@ impl Provider { pub(super) fn psa_import_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_import_key::Operation, ) -> Result { let key_name = op.key_name; let key_attributes = op.attributes; let key_data = op.data; - let key_triple = KeyTriple::new(app_name, ProviderId::MbedCrypto, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); self.key_info_store.does_not_exist(&key_triple)?; let key_id = create_key_id(&self.id_counter)?; @@ -120,11 +128,15 @@ impl Provider { pub(super) fn psa_export_public_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_public_key::Operation, ) -> Result { let key_name = op.key_name; - let key_triple = KeyTriple::new(app_name, ProviderId::MbedCrypto, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let _guard = self @@ -147,11 +159,15 @@ impl Provider { pub(super) fn psa_export_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_key::Operation, ) -> Result { let key_name = op.key_name; - let key_triple = KeyTriple::new(app_name, ProviderId::MbedCrypto, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let _guard = self @@ -174,11 +190,15 @@ impl Provider { pub(super) fn psa_destroy_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_destroy_key::Operation, ) -> Result { let key_name = op.key_name; - let key_triple = KeyTriple::new(app_name, ProviderId::MbedCrypto, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let _ = self.key_info_store.remove_key_info(&key_triple)?; diff --git a/src/providers/mbed_crypto/mod.rs b/src/providers/mbed_crypto/mod.rs index 5b035411..723c3152 100644 --- a/src/providers/mbed_crypto/mod.rs +++ b/src/providers/mbed_crypto/mod.rs @@ -4,8 +4,9 @@ //! //! This provider is a software based implementation of PSA Crypto, Mbed Crypto. use super::Provide; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::{KeyInfoManagerClient, KeyTriple}; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::{KeyIdentity, KeyInfoManagerClient}; +use crate::providers::ProviderIdentity; use derivative::Derivative; use log::{error, trace}; use parsec_interface::operations::{list_clients, list_keys, list_providers::ProviderInfo}; @@ -55,8 +56,8 @@ const SUPPORTED_OPCODES: [Opcode; 15] = [ #[derive(Derivative)] #[derivative(Debug)] pub struct Provider { - // The name of the provider set in the config. - provider_name: String, + // The identity of the provider including uuid & name. + provider_identity: ProviderIdentity, // When calling write on a reference of key_info_store, a type // std::sync::RwLockWriteGuard is returned. We need to use the @@ -95,14 +96,17 @@ impl Provider { return None; } let mbed_crypto_provider = Provider { - provider_name, + provider_identity: ProviderIdentity { + name: provider_name, + uuid: String::from(Self::PROVIDER_UUID), + }, key_info_store, key_handle_mutex: Mutex::new(()), id_counter: AtomicU32::new(key::PSA_KEY_ID_USER_MIN), }; let mut max_key_id: key::psa_key_id_t = key::PSA_KEY_ID_USER_MIN; { - let mut to_remove: Vec = Vec::new(); + let mut to_remove: Vec = Vec::new(); // Go through all MbedCryptoProvider key triple to key info mappings and check if they are still // present. // Delete those who are not present and add to the local_store the ones present. @@ -171,12 +175,12 @@ impl Provide for Provider { fn list_keys( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, _op: list_keys::Operation, ) -> Result { trace!("list_keys ingress"); Ok(list_keys::Result { - keys: self.key_info_store.list_keys(&app_name)?, + keys: self.key_info_store.list_keys(application_identity)?, }) } @@ -187,108 +191,108 @@ impl Provide for Provider { .key_info_store .list_clients()? .into_iter() - .map(|app_name| app_name.to_string()) + .map(|application_identity| application_identity.name().clone()) .collect(), }) } fn psa_generate_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_generate_key::Operation, ) -> Result { trace!("psa_generate_key ingress"); - self.psa_generate_key_internal(app_name, op) + self.psa_generate_key_internal(application_identity, op) } fn psa_import_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_import_key::Operation, ) -> Result { trace!("psa_import_key ingress"); - self.psa_import_key_internal(app_name, op) + self.psa_import_key_internal(application_identity, op) } fn psa_export_public_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_public_key::Operation, ) -> Result { trace!("psa_export_public_key ingress"); - self.psa_export_public_key_internal(app_name, op) + self.psa_export_public_key_internal(application_identity, op) } fn psa_export_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_key::Operation, ) -> Result { trace!("psa_export_key ingress"); - self.psa_export_key_internal(app_name, op) + self.psa_export_key_internal(application_identity, op) } fn psa_destroy_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_destroy_key::Operation, ) -> Result { trace!("psa_destroy_key ingress"); - self.psa_destroy_key_internal(app_name, op) + self.psa_destroy_key_internal(application_identity, op) } fn psa_sign_hash( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_sign_hash::Operation, ) -> Result { trace!("psa_sign_hash ingress"); - self.psa_sign_hash_internal(app_name, op) + self.psa_sign_hash_internal(application_identity, op) } fn psa_verify_hash( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_verify_hash::Operation, ) -> Result { trace!("psa_verify_hash ingress"); - self.psa_verify_hash_internal(app_name, op) + self.psa_verify_hash_internal(application_identity, op) } fn psa_asymmetric_encrypt( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_asymmetric_encrypt::Operation, ) -> Result { trace!("psa_asymmetric_encrypt ingress"); - self.psa_asymmetric_encrypt_internal(app_name, op) + self.psa_asymmetric_encrypt_internal(application_identity, op) } fn psa_asymmetric_decrypt( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_asymmetric_decrypt::Operation, ) -> Result { trace!("psa_asymmetric_decrypt ingress"); - self.psa_asymmetric_decrypt_internal(app_name, op) + self.psa_asymmetric_decrypt_internal(application_identity, op) } fn psa_aead_encrypt( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_aead_encrypt::Operation, ) -> Result { trace!("psa_aead_encrypt ingress"); - self.psa_aead_encrypt_internal(app_name, op) + self.psa_aead_encrypt_internal(application_identity, op) } fn psa_aead_decrypt( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_aead_decrypt::Operation, ) -> Result { trace!("psa_aead_decrypt ingress"); - self.psa_aead_decrypt_internal(app_name, op) + self.psa_aead_decrypt_internal(application_identity, op) } fn psa_hash_compute( @@ -309,11 +313,11 @@ impl Provide for Provider { fn psa_raw_key_agreement( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_raw_key_agreement::Operation, ) -> Result { trace!("psa_raw_key_agreement ingress"); - self.psa_raw_key_agreement(app_name, op) + self.psa_raw_key_agreement(application_identity, op) } fn psa_generate_random( diff --git a/src/providers/mod.rs b/src/providers/mod.rs index 0b9afeb1..23d5409b 100644 --- a/src/providers/mod.rs +++ b/src/providers/mod.rs @@ -9,6 +9,8 @@ use log::trace; use parsec_interface::requests::Opcode; use std::collections::HashSet; +use std::convert::TryFrom; +use std::fmt; pub mod core; @@ -29,7 +31,7 @@ pub mod cryptoauthlib; #[cfg(feature = "trusted-service-provider")] pub mod trusted_service; -use crate::authenticators::ApplicationName; +use crate::authenticators::ApplicationIdentity; use parsec_interface::operations::{ delete_client, list_authenticators, list_clients, list_keys, list_opcodes, list_providers, ping, psa_aead_decrypt, psa_aead_encrypt, psa_asymmetric_decrypt, psa_asymmetric_encrypt, @@ -39,6 +41,67 @@ use parsec_interface::operations::{ }; use parsec_interface::requests::{ResponseStatus, Result}; +use parsec_interface::requests::ProviderId; + +/// The ProviderIdentity struct specifies a unique uuid-name +/// combination to form a unique provider identity. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ProviderIdentity { + /// The uuid of the provider + uuid: String, + /// The name of the provider set in the config, defaults to a suitable name. + name: String, +} + +impl fmt::Display for ProviderIdentity { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "ProviderIdentity: [uuid=\"{}\", name=\"{}\"]", + self.uuid, self.name + ) + } +} + +impl ProviderIdentity { + /// Creates a new instance of ProviderIdentity. + pub fn new(uuid: String, name: String) -> ProviderIdentity { + ProviderIdentity { uuid, name } + } + + /// Get the uuid of the provider + pub fn uuid(&self) -> &String { + &self.uuid + } + + /// Get the name of the provider + pub fn name(&self) -> &String { + &self.uuid + } +} + +impl TryFrom for ProviderId { + type Error = String; + + fn try_from(provider_identity: ProviderIdentity) -> ::std::result::Result { + let provider_id = match provider_identity.uuid.as_str() { + #[cfg(feature = "cryptoauthlib-provider")] + crate::providers::cryptoauthlib::Provider::PROVIDER_UUID => Ok(ProviderId::CryptoAuthLib), + #[cfg(feature = "mbed-crypto-provider")] + crate::providers::mbed_crypto::Provider::PROVIDER_UUID => Ok(ProviderId::MbedCrypto), + #[cfg(feature = "pkcs11-provider")] + crate::providers::pkcs11::Provider::PROVIDER_UUID => Ok(ProviderId::Pkcs11), + #[cfg(feature = "tpm-provider")] + crate::providers::tpm::Provider::PROVIDER_UUID => Ok(ProviderId::Tpm), + #[cfg(feature = "trusted-service-provider")] + crate::providers::trusted_service::Provider::PROVIDER_UUID => Ok(ProviderId::TrustedService), + _ => Err(format!("Cannot convert from ProviderIdentity to ProviderId.\nProvider \"{}\" is not recognised.\nCould be it does not exist, or Parsec was not compiled with the required provider feature flags.", provider_identity.uuid)), + }?; + + Ok(provider_id) + } +} + /// Provider interface for servicing client operations /// /// Definition of the interface that a provider must implement to @@ -76,7 +139,7 @@ pub trait Provide { /// Lists all keys belonging to the application. fn list_keys( &self, - _app_name: ApplicationName, + _application_identity: &ApplicationIdentity, _op: list_keys::Operation, ) -> Result; @@ -84,7 +147,11 @@ pub trait Provide { fn list_clients(&self, _op: list_clients::Operation) -> Result; /// Delete all data a client has in the service.. - fn delete_client(&self, _op: delete_client::Operation) -> Result { + fn delete_client( + &self, + _application_identity: &ApplicationIdentity, + _op: delete_client::Operation, + ) -> Result { trace!("delete_client ingress"); Err(ResponseStatus::PsaErrorNotSupported) } @@ -113,7 +180,7 @@ pub trait Provide { /// 4. try to delete the key created. If failed, log it and return the error from 3. fn psa_generate_key( &self, - _app_name: ApplicationName, + _application_identity: &ApplicationIdentity, _op: psa_generate_key::Operation, ) -> Result { trace!("psa_generate_key ingress"); @@ -133,7 +200,7 @@ pub trait Provide { /// 4. try to delete the key imported. If failed, log it and return the error from 3. fn psa_import_key( &self, - _app_name: ApplicationName, + _application_identity: &ApplicationIdentity, _op: psa_import_key::Operation, ) -> Result { trace!("psa_import_key ingress"); @@ -143,7 +210,7 @@ pub trait Provide { /// Execute an ExportPublicKey operation. fn psa_export_public_key( &self, - _app_name: ApplicationName, + _application_identity: &ApplicationIdentity, _op: psa_export_public_key::Operation, ) -> Result { trace!("psa_export_public_key ingress"); @@ -153,7 +220,7 @@ pub trait Provide { /// Execute an ExportKey operation. fn psa_export_key( &self, - _app_name: ApplicationName, + _application_identity: &ApplicationIdentity, _op: psa_export_key::Operation, ) -> Result { trace!("psa_export_key ingress"); @@ -172,7 +239,7 @@ pub trait Provide { /// 3. try to destroy the key fn psa_destroy_key( &self, - _app_name: ApplicationName, + _application_identity: &ApplicationIdentity, _op: psa_destroy_key::Operation, ) -> Result { trace!("psa_destroy_key ingress"); @@ -183,7 +250,7 @@ pub trait Provide { /// hash it. fn psa_sign_hash( &self, - _app_name: ApplicationName, + _application_identity: &ApplicationIdentity, _op: psa_sign_hash::Operation, ) -> Result { trace!("psa_sign_hash ingress"); @@ -193,7 +260,7 @@ pub trait Provide { /// Execute a VerifyHash operation. fn psa_verify_hash( &self, - _app_name: ApplicationName, + _application_identity: &ApplicationIdentity, _op: psa_verify_hash::Operation, ) -> Result { trace!("psa_verify_hash ingress"); @@ -203,7 +270,7 @@ pub trait Provide { /// Execute an AsymmetricEncrypt operation. fn psa_asymmetric_encrypt( &self, - _app_name: ApplicationName, + _application_identity: &ApplicationIdentity, _op: psa_asymmetric_encrypt::Operation, ) -> Result { trace!("psa_asymmetric_encrypt ingress"); @@ -213,7 +280,7 @@ pub trait Provide { /// Execute an AsymmetricDecrypt operation. fn psa_asymmetric_decrypt( &self, - _app_name: ApplicationName, + _application_identity: &ApplicationIdentity, _op: psa_asymmetric_decrypt::Operation, ) -> Result { trace!("psa_asymmetric_decrypt ingress"); @@ -223,7 +290,7 @@ pub trait Provide { /// Execute an AeadEncrypt operation. fn psa_aead_encrypt( &self, - _app_name: ApplicationName, + _application_identity: &ApplicationIdentity, _op: psa_aead_encrypt::Operation, ) -> Result { trace!("psa_aead_encrypt ingress"); @@ -233,7 +300,7 @@ pub trait Provide { /// Execute an AeadDecrypt operation. fn psa_aead_decrypt( &self, - _app_name: ApplicationName, + _application_identity: &ApplicationIdentity, _op: psa_aead_decrypt::Operation, ) -> Result { trace!("psa_aead_decrypt ingress"); @@ -261,7 +328,7 @@ pub trait Provide { /// Execute a RawKeyAgreement operation. fn psa_raw_key_agreement( &self, - _app_name: ApplicationName, + _application_identity: &ApplicationIdentity, _op: psa_raw_key_agreement::Operation, ) -> Result { trace!("psa_raw_key_agreement ingress"); @@ -280,7 +347,7 @@ pub trait Provide { /// Sign a message with a private key. fn psa_sign_message( &self, - _app_name: ApplicationName, + _application_identity: &ApplicationIdentity, _op: psa_sign_message::Operation, ) -> Result { trace!("psa_sign_message ingress"); @@ -290,7 +357,7 @@ pub trait Provide { /// Verify the signature of a message using a public key. fn psa_verify_message( &self, - _app_name: ApplicationName, + _application_identity: &ApplicationIdentity, _op: psa_verify_message::Operation, ) -> Result { trace!("psa_verify_message ingress"); diff --git a/src/providers/pkcs11/asym_encryption.rs b/src/providers/pkcs11/asym_encryption.rs index fe0d4de4..9a05944f 100644 --- a/src/providers/pkcs11/asym_encryption.rs +++ b/src/providers/pkcs11/asym_encryption.rs @@ -3,22 +3,26 @@ use super::utils::to_response_status; use super::KeyPairType; use super::Provider; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::KeyTriple; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::KeyIdentity; use cryptoki::types::mechanism::Mechanism; use log::{info, trace}; use parsec_interface::operations::psa_algorithm::Algorithm; use parsec_interface::operations::{psa_asymmetric_decrypt, psa_asymmetric_encrypt}; -use parsec_interface::requests::{ProviderId, ResponseStatus, Result}; +use parsec_interface::requests::{ResponseStatus, Result}; use std::convert::TryFrom; impl Provider { pub(super) fn psa_asymmetric_encrypt_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_asymmetric_encrypt::Operation, ) -> Result { - let key_triple = KeyTriple::new(app_name, ProviderId::Pkcs11, op.key_name.clone()); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + op.key_name.clone(), + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; @@ -42,10 +46,14 @@ impl Provider { pub(super) fn psa_asymmetric_decrypt_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_asymmetric_decrypt::Operation, ) -> Result { - let key_triple = KeyTriple::new(app_name, ProviderId::Pkcs11, op.key_name.clone()); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + op.key_name.clone(), + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; @@ -69,10 +77,14 @@ impl Provider { pub(super) fn software_psa_asymmetric_encrypt_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_asymmetric_encrypt::Operation, ) -> Result { - let key_triple = KeyTriple::new(app_name, ProviderId::Pkcs11, op.key_name.clone()); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + op.key_name.clone(), + ); let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; op.validate(key_attributes)?; diff --git a/src/providers/pkcs11/asym_sign.rs b/src/providers/pkcs11/asym_sign.rs index f1bd1712..bd689cd9 100644 --- a/src/providers/pkcs11/asym_sign.rs +++ b/src/providers/pkcs11/asym_sign.rs @@ -3,23 +3,27 @@ use super::utils::to_response_status; use super::Provider; use super::{utils, KeyPairType}; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::KeyTriple; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::KeyIdentity; use cryptoki::types::mechanism::Mechanism; use log::{info, trace}; use parsec_interface::operations::psa_algorithm::Algorithm; use parsec_interface::operations::psa_key_attributes::Type; use parsec_interface::operations::{psa_sign_hash, psa_verify_hash}; -use parsec_interface::requests::{ProviderId, ResponseStatus, Result}; +use parsec_interface::requests::{ResponseStatus, Result}; use std::convert::TryFrom; impl Provider { pub(super) fn psa_sign_hash_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_sign_hash::Operation, ) -> Result { - let key_triple = KeyTriple::new(app_name, ProviderId::Pkcs11, op.key_name.clone()); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + op.key_name.clone(), + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; @@ -52,10 +56,14 @@ impl Provider { pub(super) fn psa_verify_hash_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_verify_hash::Operation, ) -> Result { - let key_triple = KeyTriple::new(app_name, ProviderId::Pkcs11, op.key_name.clone()); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + op.key_name.clone(), + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; @@ -87,10 +95,14 @@ impl Provider { pub(super) fn software_psa_verify_hash_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_verify_hash::Operation, ) -> Result { - let key_triple = KeyTriple::new(app_name, ProviderId::Pkcs11, op.key_name.clone()); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + op.key_name.clone(), + ); let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; op.validate(key_attributes)?; diff --git a/src/providers/pkcs11/key_management.rs b/src/providers/pkcs11/key_management.rs index 97bc43f2..4e77ebda 100644 --- a/src/providers/pkcs11/key_management.rs +++ b/src/providers/pkcs11/key_management.rs @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use super::utils::to_response_status; use super::{utils, KeyPairType, Provider}; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::KeyTriple; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::KeyIdentity; use cryptoki::types::mechanism::{Mechanism, MechanismType}; use cryptoki::types::object::{Attribute, AttributeType, KeyType, ObjectClass, ObjectHandle}; use cryptoki::types::session::Session; @@ -12,7 +12,7 @@ use parsec_interface::operations::psa_key_attributes::{EccFamily, Id, Lifetime, use parsec_interface::operations::{ psa_destroy_key, psa_export_public_key, psa_generate_key, psa_import_key, }; -use parsec_interface::requests::{ProviderId, ResponseStatus, Result}; +use parsec_interface::requests::{ResponseStatus, Result}; use parsec_interface::secrecy::ExposeSecret; use picky_asn1::wrapper::{IntegerAsn1, OctetStringAsn1}; use picky_asn1_x509::RSAPublicKey; @@ -47,13 +47,13 @@ impl Provider { } } - pub(super) fn move_pub_key_to_psa_crypto(&self, key_triple: &KeyTriple) -> Result { + pub(super) fn move_pub_key_to_psa_crypto(&self, key_triple: &KeyIdentity) -> Result { info!("Attempting to export public key"); let export_operation = psa_export_public_key::Operation { key_name: key_triple.key_name().to_owned(), }; let psa_export_public_key::Result { data } = - self.psa_export_public_key_internal(key_triple.app_name().clone(), export_operation)?; + self.psa_export_public_key_internal(key_triple.application(), export_operation)?; info!("Importing public key into PSA Crypto"); let mut attributes = self.key_info_store.get_key_attributes(&key_triple)?; @@ -84,7 +84,7 @@ impl Provider { pub(super) fn psa_generate_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_generate_key::Operation, ) -> Result { if op.attributes.key_type.is_public_key() { @@ -100,7 +100,11 @@ impl Provider { return Err(ResponseStatus::PsaErrorNotPermitted); } - let key_triple = KeyTriple::new(app_name, ProviderId::Pkcs11, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); self.key_info_store.does_not_exist(&key_triple)?; let session = self.new_session()?; @@ -175,7 +179,7 @@ impl Provider { pub(super) fn psa_import_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_import_key::Operation, ) -> Result { let key_name = op.key_name; @@ -186,7 +190,11 @@ impl Provider { return Err(ResponseStatus::PsaErrorNotPermitted); } - let key_triple = KeyTriple::new(app_name, ProviderId::Pkcs11, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); self.key_info_store.does_not_exist(&key_triple)?; let session = self.new_session()?; @@ -332,11 +340,15 @@ impl Provider { pub(super) fn psa_export_public_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_public_key::Operation, ) -> Result { let key_name = op.key_name; - let key_triple = KeyTriple::new(app_name, ProviderId::Pkcs11, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; let key_id = self.key_info_store.get_key_id(&key_triple)?; let session = self.new_session()?; @@ -421,11 +433,15 @@ impl Provider { pub(super) fn psa_destroy_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_destroy_key::Operation, ) -> Result { let key_name = op.key_name; - let key_triple = KeyTriple::new(app_name, ProviderId::Pkcs11, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let _ = self.key_info_store.remove_key_info(&key_triple)?; diff --git a/src/providers/pkcs11/mod.rs b/src/providers/pkcs11/mod.rs index 15586241..e6c6ec10 100644 --- a/src/providers/pkcs11/mod.rs +++ b/src/providers/pkcs11/mod.rs @@ -5,8 +5,9 @@ //! This provider allows clients to access any PKCS 11 compliant device //! through the Parsec interface. use super::Provide; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::{KeyInfoManagerClient, KeyTriple}; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::{KeyIdentity, KeyInfoManagerClient}; +use crate::providers::ProviderIdentity; use cryptoki::types::locking::CInitializeArgs; use cryptoki::types::session::{Session, UserType}; use cryptoki::types::slot_token::Slot; @@ -58,8 +59,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, + // The identity of the provider including uuid & name. + provider_identity: ProviderIdentity, #[derivative(Debug = "ignore")] key_info_store: KeyInfoManagerClient, local_ids: RwLock, @@ -101,7 +102,10 @@ impl Provider { #[allow(clippy::mutex_atomic)] let pkcs11_provider = Provider { - provider_name, + provider_identity: ProviderIdentity { + name: provider_name, + uuid: String::from(Self::PROVIDER_UUID), + }, key_info_store, local_ids: RwLock::new(HashSet::new()), backend, @@ -115,7 +119,7 @@ impl Provider { .local_ids .write() .expect("Local ID lock poisoned"); - let mut to_remove: Vec = Vec::new(); + let mut to_remove: Vec = Vec::new(); // Go through all PKCS 11 key triple to key info mappings and check if they are still // present. // Delete those who are not present and add to the local_store the ones present. @@ -245,12 +249,12 @@ impl Provide for Provider { fn list_keys( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, _op: list_keys::Operation, ) -> Result { trace!("list_keys ingress"); Ok(list_keys::Result { - keys: self.key_info_store.list_keys(&app_name)?, + keys: self.key_info_store.list_keys(application_identity)?, }) } @@ -261,91 +265,91 @@ impl Provide for Provider { .key_info_store .list_clients()? .into_iter() - .map(|app_name| app_name.to_string()) + .map(|application_identity| application_identity.name().clone()) .collect(), }) } fn psa_generate_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_generate_key::Operation, ) -> Result { trace!("psa_generate_key ingress"); - self.psa_generate_key_internal(app_name, op) + self.psa_generate_key_internal(application_identity, op) } fn psa_import_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_import_key::Operation, ) -> Result { trace!("psa_import_key ingress"); - self.psa_import_key_internal(app_name, op) + self.psa_import_key_internal(application_identity, op) } fn psa_export_public_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_public_key::Operation, ) -> Result { trace!("psa_export_public_key ingress"); - self.psa_export_public_key_internal(app_name, op) + self.psa_export_public_key_internal(application_identity, op) } fn psa_destroy_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_destroy_key::Operation, ) -> Result { trace!("psa_destroy_key ingress"); - self.psa_destroy_key_internal(app_name, op) + self.psa_destroy_key_internal(application_identity, op) } fn psa_sign_hash( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_sign_hash::Operation, ) -> Result { trace!("psa_sign_hash ingress"); - self.psa_sign_hash_internal(app_name, op) + self.psa_sign_hash_internal(application_identity, op) } fn psa_verify_hash( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_verify_hash::Operation, ) -> Result { if self.software_public_operations { trace!("software_psa_verify_hash ingress"); - self.software_psa_verify_hash_internal(app_name, op) + self.software_psa_verify_hash_internal(application_identity, op) } else { trace!("pkcs11_psa_verify_hash ingress"); - self.psa_verify_hash_internal(app_name, op) + self.psa_verify_hash_internal(application_identity, op) } } fn psa_asymmetric_encrypt( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_asymmetric_encrypt::Operation, ) -> Result { if self.software_public_operations { trace!("software_psa_asymmetric_encrypt ingress"); - self.software_psa_asymmetric_encrypt_internal(app_name, op) + self.software_psa_asymmetric_encrypt_internal(application_identity, op) } else { trace!("psa_asymmetric_encrypt ingress"); - self.psa_asymmetric_encrypt_internal(app_name, op) + self.psa_asymmetric_encrypt_internal(application_identity, op) } } fn psa_asymmetric_decrypt( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_asymmetric_decrypt::Operation, ) -> Result { trace!("psa_asymmetric_decrypt ingress"); - self.psa_asymmetric_decrypt_internal(app_name, op) + self.psa_asymmetric_decrypt_internal(application_identity, op) } } diff --git a/src/providers/tpm/asym_encryption.rs b/src/providers/tpm/asym_encryption.rs index bb0fbec8..629050aa 100644 --- a/src/providers/tpm/asym_encryption.rs +++ b/src/providers/tpm/asym_encryption.rs @@ -4,20 +4,24 @@ use super::{ utils::{self, PasswordContext}, Provider, }; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::KeyTriple; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::KeyIdentity; use parsec_interface::operations::{psa_asymmetric_decrypt, psa_asymmetric_encrypt}; -use parsec_interface::requests::{ProviderId, Result}; +use parsec_interface::requests::Result; use std::convert::TryInto; use std::ops::Deref; impl Provider { pub(super) fn psa_asymmetric_encrypt_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_asymmetric_encrypt::Operation, ) -> Result { - let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, op.key_name.clone()); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + op.key_name.clone(), + ); let mut esapi_context = self .esapi_context @@ -66,10 +70,14 @@ impl Provider { pub(super) fn psa_asymmetric_decrypt_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_asymmetric_decrypt::Operation, ) -> Result { - let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, op.key_name.clone()); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + op.key_name.clone(), + ); let mut esapi_context = self .esapi_context diff --git a/src/providers/tpm/asym_sign.rs b/src/providers/tpm/asym_sign.rs index 821ea666..9304e431 100644 --- a/src/providers/tpm/asym_sign.rs +++ b/src/providers/tpm/asym_sign.rs @@ -4,22 +4,26 @@ use super::{ utils::{self, PasswordContext}, Provider, }; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::KeyTriple; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::KeyIdentity; use log::error; use parsec_interface::operations::psa_algorithm::*; use parsec_interface::operations::{psa_sign_hash, psa_verify_hash}; -use parsec_interface::requests::{ProviderId, ResponseStatus, Result}; +use parsec_interface::requests::{ResponseStatus, Result}; use std::convert::TryFrom; use tss_esapi::structures::{Auth, Digest}; impl Provider { pub(super) fn psa_sign_hash_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_sign_hash::Operation, ) -> Result { - let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, op.key_name.clone()); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + op.key_name.clone(), + ); let mut esapi_context = self .esapi_context @@ -70,10 +74,14 @@ impl Provider { pub(super) fn psa_verify_hash_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_verify_hash::Operation, ) -> Result { - let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, op.key_name.clone()); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + op.key_name.clone(), + ); let mut esapi_context = self .esapi_context diff --git a/src/providers/tpm/key_management.rs b/src/providers/tpm/key_management.rs index e689a7de..dcdcc2ea 100644 --- a/src/providers/tpm/key_management.rs +++ b/src/providers/tpm/key_management.rs @@ -4,15 +4,15 @@ use super::utils; use super::utils::PasswordContext; use super::utils::{validate_private_key, validate_public_key, PUBLIC_EXPONENT}; use super::Provider; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::KeyTriple; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::KeyIdentity; use log::error; use parsec_interface::operations::psa_algorithm::{Algorithm, AsymmetricSignature, Hash, SignHash}; use parsec_interface::operations::psa_key_attributes::*; use parsec_interface::operations::{ psa_destroy_key, psa_export_public_key, psa_generate_key, psa_import_key, }; -use parsec_interface::requests::{ProviderId, ResponseStatus, Result}; +use parsec_interface::requests::{ResponseStatus, Result}; use parsec_interface::secrecy::ExposeSecret; use picky_asn1_x509::{RSAPrivateKey, RSAPublicKey}; use tss_esapi::abstraction::transient::RsaExponent; @@ -22,12 +22,16 @@ const AUTH_VAL_LEN: usize = 32; impl Provider { pub(super) fn psa_generate_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_generate_key::Operation, ) -> Result { let key_name = op.key_name; let attributes = op.attributes; - let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); self.key_info_store.does_not_exist(&key_triple)?; @@ -64,12 +68,12 @@ impl Provider { pub(super) fn psa_import_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_import_key::Operation, ) -> Result { match op.attributes.key_type { - Type::RsaPublicKey => self.psa_import_key_internal_rsa_public(app_name, op), - Type::RsaKeyPair => self.psa_import_key_internal_rsa_keypair(app_name, op), + Type::RsaPublicKey => self.psa_import_key_internal_rsa_public(application_identity, op), + Type::RsaKeyPair => self.psa_import_key_internal_rsa_keypair(application_identity, op), _ => { error!( "The TPM provider does not support importing for the {:?} key type.", @@ -82,7 +86,7 @@ impl Provider { pub(super) fn psa_import_key_internal_rsa_public( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_import_key::Operation, ) -> Result { // Currently only the RSA PKCS1 v1.5 signature scheme is supported @@ -97,7 +101,11 @@ impl Provider { let key_name = op.key_name; let attributes = op.attributes; - let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let key_data = op.data; self.key_info_store.does_not_exist(&key_triple)?; let mut esapi_context = self @@ -135,7 +143,7 @@ impl Provider { pub(super) fn psa_import_key_internal_rsa_keypair( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_import_key::Operation, ) -> Result { // Currently only the RSA PKCS1 v1.5 signature scheme is supported @@ -149,7 +157,11 @@ impl Provider { } let key_name = op.key_name; let attributes = op.attributes; - let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let key_data = op.data; self.key_info_store.does_not_exist(&key_triple)?; @@ -198,11 +210,15 @@ impl Provider { pub(super) fn psa_export_public_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_public_key::Operation, ) -> Result { let key_name = op.key_name; - let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let mut esapi_context = self .esapi_context @@ -226,11 +242,15 @@ impl Provider { pub(super) fn psa_destroy_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_destroy_key::Operation, ) -> Result { let key_name = op.key_name; - let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let _ = self.key_info_store.remove_key_info(&key_triple)?; diff --git a/src/providers/tpm/mod.rs b/src/providers/tpm/mod.rs index c5851876..4a380fb1 100644 --- a/src/providers/tpm/mod.rs +++ b/src/providers/tpm/mod.rs @@ -5,8 +5,9 @@ //! Provider allowing clients to use hardware or software TPM 2.0 implementations //! for their Parsec operations. use super::Provide; -use crate::authenticators::ApplicationName; +use crate::authenticators::ApplicationIdentity; use crate::key_info_managers::KeyInfoManagerClient; +use crate::providers::ProviderIdentity; use derivative::Derivative; use log::{info, trace}; use parsec_interface::operations::{list_clients, list_keys, list_providers::ProviderInfo}; @@ -56,8 +57,8 @@ 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 identity of the provider including uuid & name. + provider_identity: ProviderIdentity, // 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 @@ -83,7 +84,10 @@ impl Provider { esapi_context: tss_esapi::TransientKeyContext, ) -> Provider { Provider { - provider_name, + provider_identity: ProviderIdentity { + name: provider_name, + uuid: String::from(Self::PROVIDER_UUID), + }, esapi_context: Mutex::new(esapi_context), key_info_store, } @@ -107,12 +111,12 @@ impl Provide for Provider { fn list_keys( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, _op: list_keys::Operation, ) -> Result { trace!("list_keys ingress"); Ok(list_keys::Result { - keys: self.key_info_store.list_keys(&app_name)?, + keys: self.key_info_store.list_keys(application_identity)?, }) } @@ -123,81 +127,81 @@ impl Provide for Provider { .key_info_store .list_clients()? .into_iter() - .map(|app_name| app_name.to_string()) + .map(|application_identity| application_identity.name().clone()) .collect(), }) } fn psa_generate_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_generate_key::Operation, ) -> Result { trace!("psa_generate_key ingress"); - self.psa_generate_key_internal(app_name, op) + self.psa_generate_key_internal(application_identity, op) } fn psa_import_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_import_key::Operation, ) -> Result { trace!("psa_import_key ingress"); - self.psa_import_key_internal(app_name, op) + self.psa_import_key_internal(application_identity, op) } fn psa_export_public_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_public_key::Operation, ) -> Result { trace!("psa_export_public_key ingress"); - self.psa_export_public_key_internal(app_name, op) + self.psa_export_public_key_internal(application_identity, op) } fn psa_destroy_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_destroy_key::Operation, ) -> Result { trace!("psa_destroy_key ingress"); - self.psa_destroy_key_internal(app_name, op) + self.psa_destroy_key_internal(application_identity, op) } fn psa_sign_hash( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_sign_hash::Operation, ) -> Result { trace!("psa_sign_hash ingress"); - self.psa_sign_hash_internal(app_name, op) + self.psa_sign_hash_internal(application_identity, op) } fn psa_verify_hash( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_verify_hash::Operation, ) -> Result { trace!("psa_verify_hash ingress"); - self.psa_verify_hash_internal(app_name, op) + self.psa_verify_hash_internal(application_identity, op) } fn psa_asymmetric_encrypt( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_asymmetric_encrypt::Operation, ) -> Result { trace!("psa_asymmetric_encrypt ingress"); - self.psa_asymmetric_encrypt_internal(app_name, op) + self.psa_asymmetric_encrypt_internal(application_identity, op) } fn psa_asymmetric_decrypt( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_asymmetric_decrypt::Operation, ) -> Result { trace!("psa_asymmetric_decrypt ingress"); - self.psa_asymmetric_decrypt_internal(app_name, op) + self.psa_asymmetric_decrypt_internal(application_identity, op) } } diff --git a/src/providers/trusted_service/asym_sign.rs b/src/providers/trusted_service/asym_sign.rs index 96fc8669..df4a46f7 100644 --- a/src/providers/trusted_service/asym_sign.rs +++ b/src/providers/trusted_service/asym_sign.rs @@ -1,18 +1,22 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 use super::Provider; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::KeyTriple; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::KeyIdentity; use parsec_interface::operations::{psa_sign_hash, psa_verify_hash}; -use parsec_interface::requests::{ProviderId, Result}; +use parsec_interface::requests::Result; impl Provider { pub(super) fn psa_sign_hash_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_sign_hash::Operation, ) -> Result { - let key_triple = KeyTriple::new(app_name, ProviderId::TrustedService, op.key_name.clone()); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + op.key_name.clone(), + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; Ok(psa_sign_hash::Result { @@ -25,10 +29,14 @@ impl Provider { pub(super) fn psa_verify_hash_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_verify_hash::Operation, ) -> Result { - let key_triple = KeyTriple::new(app_name, ProviderId::TrustedService, op.key_name.clone()); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + op.key_name.clone(), + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; self.context diff --git a/src/providers/trusted_service/key_management.rs b/src/providers/trusted_service/key_management.rs index f98bec7f..ab7605d0 100644 --- a/src/providers/trusted_service/key_management.rs +++ b/src/providers/trusted_service/key_management.rs @@ -1,13 +1,13 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 use super::Provider; -use crate::authenticators::ApplicationName; -use crate::key_info_managers::KeyTriple; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::KeyIdentity; use log::error; use parsec_interface::operations::{ psa_destroy_key, psa_export_key, psa_export_public_key, psa_generate_key, psa_import_key, }; -use parsec_interface::requests::{ProviderId, ResponseStatus, Result}; +use parsec_interface::requests::{ResponseStatus, Result}; use parsec_interface::secrecy::ExposeSecret; use parsec_interface::secrecy::Secret; use psa_crypto::types::key::PSA_KEY_ID_USER_MAX; @@ -31,12 +31,16 @@ pub fn create_key_id(max_current_id: &AtomicU32) -> Result { impl Provider { pub(super) fn psa_generate_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_generate_key::Operation, ) -> Result { let key_name = op.key_name; let key_attributes = op.attributes; - let key_triple = KeyTriple::new(app_name, ProviderId::TrustedService, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); self.key_info_store.does_not_exist(&key_triple)?; let key_id = create_key_id(&self.id_counter)?; @@ -65,13 +69,17 @@ impl Provider { pub(super) fn psa_import_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_import_key::Operation, ) -> Result { let key_name = op.key_name; let key_attributes = op.attributes; let key_data = op.data; - let key_triple = KeyTriple::new(app_name, ProviderId::TrustedService, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); self.key_info_store.does_not_exist(&key_triple)?; let key_id = create_key_id(&self.id_counter)?; @@ -102,11 +110,15 @@ impl Provider { pub(super) fn psa_export_public_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_public_key::Operation, ) -> Result { let key_name = op.key_name; - let key_triple = KeyTriple::new(app_name, ProviderId::TrustedService, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; match self.context.export_public_key(key_id) { @@ -122,11 +134,15 @@ impl Provider { pub(super) fn psa_export_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_key::Operation, ) -> Result { let key_name = op.key_name; - let key_triple = KeyTriple::new(app_name, ProviderId::TrustedService, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; match self.context.export_key(key_id) { @@ -142,11 +158,15 @@ impl Provider { pub(super) fn psa_destroy_key_internal( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_destroy_key::Operation, ) -> Result { let key_name = op.key_name; - let key_triple = KeyTriple::new(app_name, ProviderId::TrustedService, key_name); + let key_triple = KeyIdentity::new( + application_identity.clone(), + self.provider_identity.clone(), + key_name, + ); let key_id = self.key_info_store.get_key_id(&key_triple)?; let _ = self.key_info_store.remove_key_info(&key_triple)?; diff --git a/src/providers/trusted_service/mod.rs b/src/providers/trusted_service/mod.rs index 4684f68e..30cca0e2 100644 --- a/src/providers/trusted_service/mod.rs +++ b/src/providers/trusted_service/mod.rs @@ -3,9 +3,9 @@ //! Trusted Service provider //! //! This provider is backed by a crypto Trusted Service deployed in TrustZone -use crate::authenticators::ApplicationName; -use crate::key_info_managers::{KeyInfoManagerClient, KeyTriple}; -use crate::providers::Provide; +use crate::authenticators::ApplicationIdentity; +use crate::key_info_managers::{KeyIdentity, KeyInfoManagerClient}; +use crate::providers::{Provide, ProviderIdentity}; use context::Context; use derivative::Derivative; use log::{error, trace}; @@ -19,6 +19,7 @@ use psa_crypto::types::key; use std::collections::HashSet; use std::sync::atomic::{AtomicU32, Ordering}; use uuid::Uuid; + mod asym_sign; mod context; mod error; @@ -42,8 +43,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, + // The identity of the provider including uuid & name. + provider_identity: ProviderIdentity, context: Context, // When calling write on a reference of key_info_store, a type @@ -71,14 +72,17 @@ impl Provider { key_info_store: KeyInfoManagerClient, ) -> anyhow::Result { let ts_provider = Provider { - provider_name, + provider_identity: ProviderIdentity { + name: provider_name, + uuid: String::from(Self::PROVIDER_UUID), + }, key_info_store, context: Context::connect()?, id_counter: AtomicU32::new(key::PSA_KEY_ID_USER_MIN), }; let mut max_key_id: key::psa_key_id_t = key::PSA_KEY_ID_USER_MIN; { - let mut to_remove: Vec = Vec::new(); + let mut to_remove: Vec = Vec::new(); // Go through all TrustedServiceProvider key triples to key info mappings and check if they are still // present. // Delete those who are not present and add to the local_store the ones present. @@ -132,12 +136,12 @@ impl Provide for Provider { fn list_keys( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, _op: list_keys::Operation, ) -> Result { trace!("list_keys ingress"); Ok(list_keys::Result { - keys: self.key_info_store.list_keys(&app_name)?, + keys: self.key_info_store.list_keys(application_identity)?, }) } @@ -148,54 +152,54 @@ impl Provide for Provider { .key_info_store .list_clients()? .into_iter() - .map(|app_name| app_name.to_string()) + .map(|application_identity| application_identity.name().clone()) .collect(), }) } fn psa_generate_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_generate_key::Operation, ) -> Result { trace!("psa_generate_key ingress"); - self.psa_generate_key_internal(app_name, op) + self.psa_generate_key_internal(application_identity, op) } fn psa_destroy_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_destroy_key::Operation, ) -> Result { trace!("psa_destroy_key ingress"); - self.psa_destroy_key_internal(app_name, op) + self.psa_destroy_key_internal(application_identity, op) } fn psa_import_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_import_key::Operation, ) -> Result { trace!("psa_import_key ingress"); - self.psa_import_key_internal(app_name, op) + self.psa_import_key_internal(application_identity, op) } fn psa_export_public_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_public_key::Operation, ) -> Result { trace!("psa_export_public_key ingress"); - self.psa_export_public_key_internal(app_name, op) + self.psa_export_public_key_internal(application_identity, op) } fn psa_export_key( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_export_key::Operation, ) -> Result { trace!("psa_export_key ingress"); - self.psa_export_key_internal(app_name, op) + self.psa_export_key_internal(application_identity, op) } fn psa_generate_random( @@ -208,20 +212,20 @@ impl Provide for Provider { fn psa_sign_hash( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_sign_hash::Operation, ) -> Result { trace!("psa_sign_hash ingress"); - self.psa_sign_hash_internal(app_name, op) + self.psa_sign_hash_internal(application_identity, op) } fn psa_verify_hash( &self, - app_name: ApplicationName, + application_identity: &ApplicationIdentity, op: psa_verify_hash::Operation, ) -> Result { trace!("psa_verify_hash ingress"); - self.psa_verify_hash_internal(app_name, op) + self.psa_verify_hash_internal(application_identity, op) } } diff --git a/src/utils/service_builder.rs b/src/utils/service_builder.rs index 5fa9a32a..44254b8a 100644 --- a/src/utils/service_builder.rs +++ b/src/utils/service_builder.rs @@ -50,6 +50,26 @@ use crate::providers::tpm::ProviderBuilder as TpmProviderBuilder; #[cfg(feature = "trusted-service-provider")] use crate::providers::trusted_service::ProviderBuilder as TrustedServiceProviderBuilder; +#[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(any( + feature = "mbed-crypto-provider", + feature = "pkcs11-provider", + feature = "tpm-provider", + feature = "cryptoauthlib-provider", + feature = "trusted-service-provider" +))] +use crate::providers::ProviderIdentity; + #[cfg(any( feature = "mbed-crypto-provider", feature = "pkcs11-provider", @@ -282,9 +302,13 @@ unsafe fn get_provider( #[cfg(feature = "mbed-crypto-provider")] ProviderConfig::MbedCrypto { .. } => { info!("Creating a Mbed Crypto Provider."); + let provider_identity = ProviderIdentity::new( + MbedCryptoProvider::PROVIDER_UUID.to_string(), + config.provider_name()?, + ); Ok(Some(Arc::new( MbedCryptoProviderBuilder::new() - .with_key_info_store(kim_factory.build_client(ProviderId::MbedCrypto)) + .with_key_info_store(kim_factory.build_client(provider_identity)) .with_provider_name(config.provider_name()?) .build()?, ))) @@ -299,9 +323,13 @@ unsafe fn get_provider( .. } => { info!("Creating a PKCS 11 Provider."); + let provider_identity = ProviderIdentity::new( + Pkcs11Provider::PROVIDER_UUID.to_string(), + config.provider_name()?, + ); Ok(Some(Arc::new( Pkcs11ProviderBuilder::new() - .with_key_info_store(kim_factory.build_client(ProviderId::Pkcs11)) + .with_key_info_store(kim_factory.build_client(provider_identity)) .with_provider_name(config.provider_name()?) .with_pkcs11_library_path(library_path.clone()) .with_slot_number(*slot_number) @@ -322,6 +350,11 @@ unsafe fn get_provider( use tss_esapi::tcti_ldr::{TctiContext, TctiNameConf}; info!("Creating a TPM Provider."); + let provider_identity = ProviderIdentity::new( + TpmProvider::PROVIDER_UUID.to_string(), + config.provider_name()?, + ); + let tcti_name_conf = TctiNameConf::from_str(tcti).map_err(|_| { std::io::Error::new(ErrorKind::InvalidData, "Invalid TCTI configuration string") })?; @@ -342,7 +375,7 @@ unsafe fn get_provider( Ok(Some(Arc::new( TpmProviderBuilder::new() - .with_key_info_store(kim_factory.build_client(ProviderId::Tpm)) + .with_key_info_store(kim_factory.build_client(provider_identity)) .with_provider_name(config.provider_name()?) .with_tcti(tcti) .with_owner_hierarchy_auth(owner_hierarchy_auth.clone()) @@ -362,9 +395,13 @@ unsafe fn get_provider( .. } => { info!("Creating a CryptoAuthentication Library Provider."); + let provider_identity = ProviderIdentity::new( + CryptoAuthLibProvider::PROVIDER_UUID.to_string(), + config.provider_name()?, + ); Ok(Some(Arc::new( CryptoAuthLibProviderBuilder::new() - .with_key_info_store(kim_factory.build_client(ProviderId::CryptoAuthLib)) + .with_key_info_store(kim_factory.build_client(provider_identity)) .with_provider_name(config.provider_name()?) .with_device_type(device_type.to_string()) .with_iface_type(iface_type.to_string()) @@ -380,9 +417,13 @@ unsafe fn get_provider( #[cfg(feature = "trusted-service-provider")] ProviderConfig::TrustedService { .. } => { info!("Creating a TPM Provider."); + let provider_identity = ProviderIdentity::new( + TrustedServiceProvider::PROVIDER_UUID.to_string(), + config.provider_name()?, + ); Ok(Some(Arc::new( TrustedServiceProviderBuilder::new() - .with_key_info_store(kim_factory.build_client(ProviderId::TrustedService)) + .with_key_info_store(kim_factory.build_client(provider_identity)) .with_provider_name(config.provider_name()?) .build()?, )))