-
Notifications
You must be signed in to change notification settings - Fork 72
Add list keys #261
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add list keys #261
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ | |
use crate::authenticators::ApplicationName; | ||
use crate::providers::Provide; | ||
use derivative::Derivative; | ||
use log::trace; | ||
use log::{error, trace}; | ||
use parsec_interface::operations::Convert; | ||
use parsec_interface::operations::{NativeOperation, NativeResult}; | ||
use parsec_interface::requests::{ | ||
|
@@ -53,12 +53,19 @@ impl BackEndHandler { | |
/// the request. | ||
/// | ||
/// # Errors | ||
/// - if the provider ID can not perform the type of operation, returns | ||
/// `ResponseStatus::PsaErrorNotSupported` | ||
/// - if the provider ID does not match, returns `ResponseStatus::WrongProviderID` | ||
/// - if the content type does not match, returns `ResponseStatus::ContentTypeNotSupported` | ||
/// - if the accept type does not match, returns `ResponseStatus::AcceptTypeNotSupported` | ||
pub fn is_capable(&self, request: &Request) -> Result<()> { | ||
let header = &request.header; | ||
|
||
if (self.provider_id == ProviderID::Core) != header.opcode.is_core() { | ||
error!("The request's operation is not compatible with the provider targeted."); | ||
return Err(ResponseStatus::PsaErrorNotSupported); | ||
} | ||
|
||
if header.provider != self.provider_id { | ||
Err(ResponseStatus::WrongProviderID) | ||
} else if header.content_type != self.content_type { | ||
|
@@ -207,6 +214,14 @@ impl BackEndHandler { | |
trace!("list_authenticators egress"); | ||
self.result_to_response(NativeResult::ListAuthenticators(result), header) | ||
} | ||
NativeOperation::ListKeys(op_list_keys) => { | ||
let app_name = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The check I was talking in the other comment could be here but could also be in the |
||
unwrap_or_else_return!(app_name.ok_or(ResponseStatus::NotAuthenticated)); | ||
let result = | ||
unwrap_or_else_return!(self.provider.list_keys(app_name, op_list_keys)); | ||
trace!("list_keys egress"); | ||
self.result_to_response(NativeResult::ListKeys(result), header) | ||
} | ||
NativeOperation::PsaHashCompute(op_hash_compute) => { | ||
let _app_name = | ||
unwrap_or_else_return!(app_name.ok_or(ResponseStatus::NotAuthenticated)); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -145,3 +145,40 @@ pub trait ManageKeyInfo { | |
/// Returns an error as a String if there was a problem accessing the Key Info Manager. | ||
fn exists(&self, key_triple: &KeyTriple) -> Result<bool, String>; | ||
} | ||
|
||
/// Returns a Vec of the KeyInfo objects corresponding to the given application name and | ||
/// provider ID. | ||
/// | ||
/// # Errors | ||
/// | ||
/// Returns an error as a String if there was a problem accessing the Key Info Manager. | ||
pub fn list_keys( | ||
manager: &dyn ManageKeyInfo, | ||
app_name: &ApplicationName, | ||
provider_id: ProviderID, | ||
) -> Result<Vec<parsec_interface::operations::list_keys::KeyInfo>, String> { | ||
use parsec_interface::operations::list_keys::KeyInfo; | ||
|
||
let mut keys: Vec<KeyInfo> = Vec::new(); | ||
let key_triples = manager.get_all(provider_id)?; | ||
|
||
for key_triple in key_triples { | ||
if key_triple.app_name() != app_name { | ||
continue; | ||
} | ||
|
||
let key_info = manager.get(key_triple)?; | ||
let key_info = match key_info { | ||
Some(key_info) => key_info, | ||
_ => continue, | ||
}; | ||
|
||
keys.push(KeyInfo { | ||
provider_id: ProviderID::MbedCrypto, | ||
name: key_triple.key_name().to_string(), | ||
attributes: key_info.attributes, | ||
}); | ||
} | ||
|
||
Ok(keys) | ||
} | ||
Comment on lines
+155
to
+184
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can actually include this in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason why I did not include it is to prevent overwriting this method. I think the result is the same? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
To prevent overwriting what?
It is, in the end, I just tend to prefer methods to functions when the function is clearly acting on a specific type. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well I might be wrong but if a method is in a trait then implementation can either not implement this method and use the default implementation, or overwrite it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, yes, true, but we have control over that. And it might be that that's an advantage, because for a database, for example, we might be able to build a query to get only the entries that match those requirements instead of filtering ourselves. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -91,9 +91,9 @@ impl ProviderConfig { | |
|
||
use crate::authenticators::ApplicationName; | ||
use parsec_interface::operations::{ | ||
list_authenticators, list_opcodes, list_providers, ping, psa_aead_decrypt, psa_aead_encrypt, | ||
psa_asymmetric_decrypt, psa_asymmetric_encrypt, psa_destroy_key, psa_export_key, | ||
psa_export_public_key, psa_generate_key, psa_generate_random, psa_hash_compare, | ||
list_authenticators, list_keys, list_opcodes, list_providers, ping, psa_aead_decrypt, | ||
psa_aead_encrypt, psa_asymmetric_decrypt, psa_asymmetric_encrypt, psa_destroy_key, | ||
psa_export_key, psa_export_public_key, psa_generate_key, psa_generate_random, psa_hash_compare, | ||
psa_hash_compute, psa_import_key, psa_raw_key_agreement, psa_sign_hash, psa_verify_hash, | ||
}; | ||
use parsec_interface::requests::{ResponseStatus, Result}; | ||
|
@@ -132,6 +132,16 @@ pub trait Provide { | |
Err(ResponseStatus::PsaErrorNotSupported) | ||
} | ||
|
||
/// Lists all keys belonging to the application. | ||
fn list_keys( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be nicer to only have the
Although we need to be sure somewhere that |
||
&self, | ||
_app_name: ApplicationName, | ||
_op: list_keys::Operation, | ||
) -> Result<list_keys::Result> { | ||
trace!("list_keys ingress"); | ||
Err(ResponseStatus::PsaErrorNotSupported) | ||
} | ||
|
||
/// Execute a Ping operation to get the wire protocol version major and minor information. | ||
/// | ||
/// # Errors | ||
|
Uh oh!
There was an error while loading. Please reload this page.