Skip to content

Commit

Permalink
Added the changes required for the CanDoCrypto operation.
Browse files Browse the repository at this point in the history
Added new files cntaining the CanDoCrypto operation generated from the protobuf contract, the rust version of the operation and the conversion between the rust and the protobuf values. Also added changes to the relvent mod.rs files so that the new files are included.

Signed-off-by: Sam Davis <[email protected]>
  • Loading branch information
Kakemone committed Sep 14, 2021
1 parent 79b6f18 commit 8527a3a
Show file tree
Hide file tree
Showing 7 changed files with 297 additions and 2 deletions.
33 changes: 33 additions & 0 deletions src/operations/can_do_crypto.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
//! # CanDoCrypto operation
//!
//! Checks if the provider supports the input attributes for the operations of a given type
use super::psa_key_attributes::Attributes;

/// Public enum which stores the options for the types of check
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
pub enum CheckType {
/// Using a specific algorithm with an existing key.
Use,
/// Generating a key and optionally using it for a specific algorithm.
Generate,
/// Importing a key and optionally using it for a specific algorithm.
Import,
/// Deriving a key and optionally using it for a specific algorithm (to be checked)
Derive,
}

/// Native object for client deleting operation.
#[derive(Clone, Debug, Copy)]
pub struct Operation {
/// The type of check required
pub check_type: CheckType,
/// The attributes that are to be checked
pub attributes: Attributes,
}

/// Native object for client deleting result.
#[derive(Copy, Clone, Debug)]
pub struct Result;
19 changes: 19 additions & 0 deletions src/operations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub mod delete_client;
pub mod list_clients;
pub mod psa_generate_random;
pub mod psa_raw_key_agreement;
pub mod can_do_crypto;

pub use psa_crypto::types::algorithm as psa_algorithm;
pub use psa_crypto::types::key as psa_key_attributes;
Expand Down Expand Up @@ -91,6 +92,8 @@ pub enum NativeOperation {
PsaSignMessage(psa_sign_message::Operation),
/// PsaVerifyMessage operation
PsaVerifyMessage(psa_verify_message::Operation),
/// CanDoCrypto operation
CanDoCrypto(can_do_crypto::Operation),
}

impl NativeOperation {
Expand Down Expand Up @@ -121,6 +124,7 @@ impl NativeOperation {
NativeOperation::PsaRawKeyAgreement(_) => Opcode::PsaRawKeyAgreement,
NativeOperation::PsaSignMessage(_) => Opcode::PsaSignMessage,
NativeOperation::PsaVerifyMessage(_) => Opcode::PsaVerifyMessage,
NativeOperation::CanDoCrypto(_) => Opcode::CanDoCrypto,
}
}
}
Expand Down Expand Up @@ -177,6 +181,8 @@ pub enum NativeResult {
PsaSignMessage(psa_sign_message::Result),
/// PsaVerifyMessage result
PsaVerifyMessage(psa_verify_message::Result),
/// CanDoCrypto result
CanDoCrypto(can_do_crypto::Result),
}

impl NativeResult {
Expand Down Expand Up @@ -207,6 +213,7 @@ impl NativeResult {
NativeResult::PsaRawKeyAgreement(_) => Opcode::PsaRawKeyAgreement,
NativeResult::PsaSignMessage(_) => Opcode::PsaSignMessage,
NativeResult::PsaVerifyMessage(_) => Opcode::PsaVerifyMessage,
NativeResult::CanDoCrypto(_) => Opcode::CanDoCrypto,
}
}
}
Expand Down Expand Up @@ -383,6 +390,12 @@ impl From<psa_verify_message::Operation> for NativeOperation {
}
}

impl From<can_do_crypto::Operation> for NativeOperation {
fn from(op: can_do_crypto::Operation) -> Self {
NativeOperation::CanDoCrypto(op)
}
}

impl From<list_providers::Result> for NativeResult {
fn from(op: list_providers::Result) -> Self {
NativeResult::ListProviders(op)
Expand Down Expand Up @@ -526,3 +539,9 @@ impl From<psa_verify_message::Result> for NativeResult {
NativeResult::PsaVerifyMessage(op)
}
}

impl From<can_do_crypto::Result> for NativeResult {
fn from(op: can_do_crypto::Result) -> Self {
NativeResult::CanDoCrypto(op)
}
}
186 changes: 186 additions & 0 deletions src/operations_protobuf/convert_can_do_crypto.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
// Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use super::generated_ops::can_do_crypto::{
CheckType as CheckTypeProto, Operation as OperationProto, Result as ResultProto,
};
use crate::operations::can_do_crypto::{CheckType, Operation, Result};
use crate::requests::ResponseStatus;
use log::error;
use std::convert::{TryFrom, TryInto};

impl TryFrom<OperationProto> for Operation {
type Error = ResponseStatus;

fn try_from(proto_op: OperationProto) -> std::result::Result<Self, Self::Error> {
let key_attributes = proto_op.attributes.ok_or_else(|| {
error!("The attributes field of CanDoCrypto::Operation message is not set (mandatory field).");
ResponseStatus::InvalidEncoding
})?;
Ok(Operation {
check_type: i32_to_check_type(proto_op.check_type)?,
attributes: key_attributes.try_into()?,
})
}
}

impl TryFrom<Operation> for OperationProto {
type Error = ResponseStatus;

fn try_from(op: Operation) -> std::result::Result<Self, Self::Error> {
Ok(OperationProto {
check_type: check_type_to_i32(op.check_type),
attributes: Some(op.attributes.try_into()?),
})
}
}

impl TryFrom<Result> for ResultProto {
type Error = ResponseStatus;

fn try_from(_result: Result) -> std::result::Result<Self, Self::Error> {
Ok(ResultProto {})
}
}

impl TryFrom<ResultProto> for Result {
type Error = ResponseStatus;

fn try_from(_response: ResultProto) -> std::result::Result<Self, Self::Error> {
Ok(Result {})
}
}

// CheckType: from protobuf to native
impl TryFrom<CheckTypeProto> for CheckType {
type Error = ResponseStatus;

fn try_from(check_type_proto_val: CheckTypeProto) -> std::result::Result<Self, Self::Error> {
match check_type_proto_val {
CheckTypeProto::ChecktypeNone => Err(ResponseStatus::InvalidEncoding),
CheckTypeProto::Use => Ok(CheckType::Use),
CheckTypeProto::Generate => Ok(CheckType::Generate),
CheckTypeProto::Import => Ok(CheckType::Import),
CheckTypeProto::Derive => Ok(CheckType::Derive),
}
}
}

// CheckType: from native to protobuf
impl TryFrom<CheckType> for CheckTypeProto {
type Error = ResponseStatus;

fn try_from(check_type_val: CheckType) -> std::result::Result<Self, Self::Error> {
match check_type_val {
CheckType::Use => Ok(CheckTypeProto::Use),
CheckType::Generate => Ok(CheckTypeProto::Generate),
CheckType::Import => Ok(CheckTypeProto::Import),
CheckType::Derive => Ok(CheckTypeProto::Derive),
}
}
}

// CheckType from protobuf to native
pub fn i32_to_check_type(check_type_val: i32) -> std::result::Result<CheckType, ResponseStatus> {
let check_type_proto: CheckTypeProto = check_type_val.try_into()?;
check_type_proto.try_into()
}

// CheckType from native to protobuf
pub fn check_type_to_i32(check_type: CheckType) -> i32 {
match check_type {
CheckType::Use => CheckTypeProto::Use.into(),
CheckType::Generate => CheckTypeProto::Generate.into(),
CheckType::Import => CheckTypeProto::Import.into(),
CheckType::Derive => CheckTypeProto::Derive.into(),
}
}

#[cfg(test)]
mod test {

use super::super::generated_ops::can_do_crypto::Operation as OperationProto;
use crate::operations::can_do_crypto::{CheckType, Operation};
use crate::operations::psa_algorithm::{Algorithm, AsymmetricSignature, Hash};
use crate::operations::psa_key_attributes::{self, Attributes, Lifetime, Policy, UsageFlags};
use crate::operations_protobuf::convert_can_do_crypto::check_type_to_i32;
use std::convert::TryInto;

#[test]
fn proto_to_resp() {
let mut usage_flags: UsageFlags = Default::default();
let _ = usage_flags
.set_export()
.set_copy()
.set_cache()
.set_encrypt()
.set_decrypt()
.set_sign_message()
.set_verify_message()
.set_sign_hash()
.set_verify_hash()
.set_derive();
let key_attrs = Attributes {
lifetime: Lifetime::Persistent,
key_type: psa_key_attributes::Type::RsaKeyPair,
bits: 1024,
policy: Policy {
usage_flags,
permitted_algorithms: Algorithm::AsymmetricSignature(
AsymmetricSignature::RsaPkcs1v15Sign {
hash_alg: Hash::Sha1.into(),
},
),
},
};
let proto = OperationProto {
check_type: check_type_to_i32(CheckType::Use),
attributes: Some(key_attrs.try_into().expect("Failed conversion")),
};

let resp: Operation = proto.try_into().expect("Failed conversion");

assert_eq!(resp.check_type, CheckType::Use);
assert_eq!(resp.attributes, key_attrs);
}

#[test]
fn resp_to_proto() {
let mut usage_flags: UsageFlags = Default::default();
let _ = usage_flags
.set_export()
.set_copy()
.set_cache()
.set_encrypt()
.set_decrypt()
.set_sign_message()
.set_verify_message()
.set_sign_hash()
.set_verify_hash()
.set_derive();
let key_attrs = Attributes {
lifetime: Lifetime::Persistent,
key_type: psa_key_attributes::Type::RsaKeyPair,
bits: 1024,
policy: Policy {
usage_flags,
permitted_algorithms: Algorithm::AsymmetricSignature(
AsymmetricSignature::RsaPkcs1v15Sign {
hash_alg: Hash::Sha1.into(),
},
),
},
};
let resp: Operation = Operation {
check_type: CheckType::Use,
attributes: key_attrs,
};

let proto: OperationProto = resp.try_into().expect("Failed conversion");

assert_eq!(proto.check_type, check_type_to_i32(CheckType::Use));
assert_eq!(
proto.attributes.expect("Failed conversion"),
key_attrs.try_into().expect("Failed conversion")
);
}
}
19 changes: 19 additions & 0 deletions src/operations_protobuf/generated_ops/can_do_crypto.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Operation {
#[prost(enumeration="CheckType", tag="1")]
pub check_type: i32,
#[prost(message, optional, tag="2")]
pub attributes: ::std::option::Option<super::psa_key_attributes::KeyAttributes>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Result {
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum CheckType {
ChecktypeNone = 0,
Use = 1,
Generate = 2,
Import = 3,
Derive = 4,
}
17 changes: 17 additions & 0 deletions src/operations_protobuf/generated_ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ pub mod psa_generate_random;
pub mod psa_hash_compute;
pub mod psa_hash_compare;
pub mod psa_raw_key_agreement;
pub mod can_do_crypto;

use zeroize::Zeroize;

use crate::requests::{ResponseStatus, Result};
use log::error;
use psa_algorithm::algorithm::{aead::AeadWithDefaultLengthTag, key_agreement::Raw, Cipher, Hash};
use psa_key_attributes::key_type::{DhFamily, EccFamily};
use can_do_crypto::CheckType;
use std::convert::TryFrom;

impl TryFrom<i32> for Cipher {
Expand Down Expand Up @@ -114,6 +116,19 @@ impl TryFrom<i32> for DhFamily {
}
}

impl TryFrom<i32> for CheckType {
type Error = ResponseStatus;
fn try_from(check_type_val: i32) -> Result<Self> {
CheckType::from_i32(check_type_val).ok_or_else(|| {
error!(
"Value {} not supported as a check type.",
check_type_val
);
ResponseStatus::InvalidEncoding
})
}
}

pub(super) trait ClearProtoMessage {
fn clear_message(&mut self) {}
}
Expand Down Expand Up @@ -152,6 +167,8 @@ empty_clear_message!(psa_verify_hash::Result);
empty_clear_message!(psa_verify_message::Result);
empty_clear_message!(psa_generate_random::Operation);
empty_clear_message!(psa_hash_compare::Result);
empty_clear_message!(can_do_crypto::Operation);
empty_clear_message!(can_do_crypto::Result);

impl ClearProtoMessage for psa_sign_hash::Operation {
fn clear_message(&mut self) {
Expand Down
Loading

0 comments on commit 8527a3a

Please sign in to comment.