diff --git a/Cargo.toml b/Cargo.toml index 6fb88e7..cf326c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,3 +26,6 @@ mockstream = "0.0.3" [features] testing = ["parsec-interface/testing", "no-fs-permission-check"] no-fs-permission-check = [] + +[patch.crates-io] +parsec-interface = { git = "https://github.com/parallaxsecond/parsec-interface-rs.git", rev = "ce3590dc0cb7f345f328fec0dc22073da1b4699c" } diff --git a/src/core/basic_client.rs b/src/core/basic_client.rs index d763028..f635c12 100644 --- a/src/core/basic_client.rs +++ b/src/core/basic_client.rs @@ -7,6 +7,7 @@ use crate::error::{ClientErrorKind, Error, Result}; use parsec_interface::operations::list_authenticators::{ AuthenticatorInfo, Operation as ListAuthenticators, }; +use parsec_interface::operations::list_keys::{KeyInfo, Operation as ListKeys}; use parsec_interface::operations::list_opcodes::Operation as ListOpcodes; use parsec_interface::operations::list_providers::{Operation as ListProviders, ProviderInfo}; use parsec_interface::operations::ping::Operation as Ping; @@ -271,6 +272,22 @@ impl BasicClient { } } + /// **[Core Operation]** List all keys belonging to the application. + pub fn list_keys(&self) -> Result> { + let res = self.op_client.process_operation( + NativeOperation::ListKeys(ListKeys {}), + ProviderID::Core, + &self.auth_data, + )?; + if let NativeResult::ListKeys(res) = res { + Ok(res.keys) + } else { + // Should really not be reached given the checks we do, but it's not impossible if some + // changes happen in the interface + Err(Error::Client(ClientErrorKind::InvalidServiceResponseType)) + } + } + /// **[Core Operation]** Send a ping request to the service. /// /// This operation is intended for testing connectivity to the diff --git a/src/core/testing/core_tests.rs b/src/core/testing/core_tests.rs index b23500c..590fb86 100644 --- a/src/core/testing/core_tests.rs +++ b/src/core/testing/core_tests.rs @@ -6,6 +6,7 @@ use crate::error::{ClientErrorKind, Error}; use crate::BasicClient; use mockstream::{FailingMockStream, MockStream}; use parsec_interface::operations; +use parsec_interface::operations::list_keys::KeyInfo; use parsec_interface::operations::list_providers::{ProviderInfo, Uuid}; use parsec_interface::operations::psa_algorithm::*; use parsec_interface::operations::psa_key_attributes::*; @@ -118,6 +119,57 @@ fn list_opcodes_test() { assert!(opcodes.contains(&Opcode::PsaGenerateKey) && opcodes.contains(&Opcode::PsaDestroyKey)); } +#[test] +fn list_keys_test() { + use parsec_interface::operations::psa_key_attributes::{ + Attributes, Lifetime, Policy, Type, UsageFlags, + }; + + let mut client: TestBasicClient = Default::default(); + let mut key_info = Vec::new(); + key_info.push(KeyInfo { + provider_id: ProviderID::MbedCrypto, + name: String::from("Foo"), + attributes: Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaKeyPair, + bits: 1024, + policy: Policy { + usage_flags: UsageFlags { + export: true, + copy: true, + cache: true, + encrypt: true, + decrypt: true, + sign_message: true, + verify_message: true, + sign_hash: true, + verify_hash: true, + derive: true, + }, + permitted_algorithms: Algorithm::AsymmetricSignature( + AsymmetricSignature::RsaPkcs1v15Sign { + hash_alg: Hash::Sha256.into(), + }, + ), + }, + }, + }); + + client.set_mock_read(&get_response_bytes_from_result(NativeResult::ListKeys( + operations::list_keys::Result { keys: key_info }, + ))); + + let keys = client.list_keys().expect("Failed to list keys"); + // Check request: + // ListKeys request is empty so no checking to be done + + // Check response: + assert_eq!(keys.len(), 1); + assert_eq!(keys[0].name, "Foo"); + assert_eq!(keys[0].provider_id, ProviderID::MbedCrypto); +} + #[test] fn no_crypto_provider_test() { let client = BasicClient::new(AuthenticationData::AppIdentity(Secret::new(String::from(