Skip to content

Commit 8527a3a

Browse files
committed
Added the changes required for the CanDoCrypto operation.
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]>
1 parent 79b6f18 commit 8527a3a

File tree

7 files changed

+297
-2
lines changed

7 files changed

+297
-2
lines changed

src/operations/can_do_crypto.rs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2021 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
//! # CanDoCrypto operation
4+
//!
5+
//! Checks if the provider supports the input attributes for the operations of a given type
6+
7+
use super::psa_key_attributes::Attributes;
8+
9+
/// Public enum which stores the options for the types of check
10+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
11+
pub enum CheckType {
12+
/// Using a specific algorithm with an existing key.
13+
Use,
14+
/// Generating a key and optionally using it for a specific algorithm.
15+
Generate,
16+
/// Importing a key and optionally using it for a specific algorithm.
17+
Import,
18+
/// Deriving a key and optionally using it for a specific algorithm (to be checked)
19+
Derive,
20+
}
21+
22+
/// Native object for client deleting operation.
23+
#[derive(Clone, Debug, Copy)]
24+
pub struct Operation {
25+
/// The type of check required
26+
pub check_type: CheckType,
27+
/// The attributes that are to be checked
28+
pub attributes: Attributes,
29+
}
30+
31+
/// Native object for client deleting result.
32+
#[derive(Copy, Clone, Debug)]
33+
pub struct Result;

src/operations/mod.rs

+19
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub mod delete_client;
3333
pub mod list_clients;
3434
pub mod psa_generate_random;
3535
pub mod psa_raw_key_agreement;
36+
pub mod can_do_crypto;
3637

3738
pub use psa_crypto::types::algorithm as psa_algorithm;
3839
pub use psa_crypto::types::key as psa_key_attributes;
@@ -91,6 +92,8 @@ pub enum NativeOperation {
9192
PsaSignMessage(psa_sign_message::Operation),
9293
/// PsaVerifyMessage operation
9394
PsaVerifyMessage(psa_verify_message::Operation),
95+
/// CanDoCrypto operation
96+
CanDoCrypto(can_do_crypto::Operation),
9497
}
9598

9699
impl NativeOperation {
@@ -121,6 +124,7 @@ impl NativeOperation {
121124
NativeOperation::PsaRawKeyAgreement(_) => Opcode::PsaRawKeyAgreement,
122125
NativeOperation::PsaSignMessage(_) => Opcode::PsaSignMessage,
123126
NativeOperation::PsaVerifyMessage(_) => Opcode::PsaVerifyMessage,
127+
NativeOperation::CanDoCrypto(_) => Opcode::CanDoCrypto,
124128
}
125129
}
126130
}
@@ -177,6 +181,8 @@ pub enum NativeResult {
177181
PsaSignMessage(psa_sign_message::Result),
178182
/// PsaVerifyMessage result
179183
PsaVerifyMessage(psa_verify_message::Result),
184+
/// CanDoCrypto result
185+
CanDoCrypto(can_do_crypto::Result),
180186
}
181187

182188
impl NativeResult {
@@ -207,6 +213,7 @@ impl NativeResult {
207213
NativeResult::PsaRawKeyAgreement(_) => Opcode::PsaRawKeyAgreement,
208214
NativeResult::PsaSignMessage(_) => Opcode::PsaSignMessage,
209215
NativeResult::PsaVerifyMessage(_) => Opcode::PsaVerifyMessage,
216+
NativeResult::CanDoCrypto(_) => Opcode::CanDoCrypto,
210217
}
211218
}
212219
}
@@ -383,6 +390,12 @@ impl From<psa_verify_message::Operation> for NativeOperation {
383390
}
384391
}
385392

393+
impl From<can_do_crypto::Operation> for NativeOperation {
394+
fn from(op: can_do_crypto::Operation) -> Self {
395+
NativeOperation::CanDoCrypto(op)
396+
}
397+
}
398+
386399
impl From<list_providers::Result> for NativeResult {
387400
fn from(op: list_providers::Result) -> Self {
388401
NativeResult::ListProviders(op)
@@ -526,3 +539,9 @@ impl From<psa_verify_message::Result> for NativeResult {
526539
NativeResult::PsaVerifyMessage(op)
527540
}
528541
}
542+
543+
impl From<can_do_crypto::Result> for NativeResult {
544+
fn from(op: can_do_crypto::Result) -> Self {
545+
NativeResult::CanDoCrypto(op)
546+
}
547+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
// Copyright 2021 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
use super::generated_ops::can_do_crypto::{
4+
CheckType as CheckTypeProto, Operation as OperationProto, Result as ResultProto,
5+
};
6+
use crate::operations::can_do_crypto::{CheckType, Operation, Result};
7+
use crate::requests::ResponseStatus;
8+
use log::error;
9+
use std::convert::{TryFrom, TryInto};
10+
11+
impl TryFrom<OperationProto> for Operation {
12+
type Error = ResponseStatus;
13+
14+
fn try_from(proto_op: OperationProto) -> std::result::Result<Self, Self::Error> {
15+
let key_attributes = proto_op.attributes.ok_or_else(|| {
16+
error!("The attributes field of CanDoCrypto::Operation message is not set (mandatory field).");
17+
ResponseStatus::InvalidEncoding
18+
})?;
19+
Ok(Operation {
20+
check_type: i32_to_check_type(proto_op.check_type)?,
21+
attributes: key_attributes.try_into()?,
22+
})
23+
}
24+
}
25+
26+
impl TryFrom<Operation> for OperationProto {
27+
type Error = ResponseStatus;
28+
29+
fn try_from(op: Operation) -> std::result::Result<Self, Self::Error> {
30+
Ok(OperationProto {
31+
check_type: check_type_to_i32(op.check_type),
32+
attributes: Some(op.attributes.try_into()?),
33+
})
34+
}
35+
}
36+
37+
impl TryFrom<Result> for ResultProto {
38+
type Error = ResponseStatus;
39+
40+
fn try_from(_result: Result) -> std::result::Result<Self, Self::Error> {
41+
Ok(ResultProto {})
42+
}
43+
}
44+
45+
impl TryFrom<ResultProto> for Result {
46+
type Error = ResponseStatus;
47+
48+
fn try_from(_response: ResultProto) -> std::result::Result<Self, Self::Error> {
49+
Ok(Result {})
50+
}
51+
}
52+
53+
// CheckType: from protobuf to native
54+
impl TryFrom<CheckTypeProto> for CheckType {
55+
type Error = ResponseStatus;
56+
57+
fn try_from(check_type_proto_val: CheckTypeProto) -> std::result::Result<Self, Self::Error> {
58+
match check_type_proto_val {
59+
CheckTypeProto::ChecktypeNone => Err(ResponseStatus::InvalidEncoding),
60+
CheckTypeProto::Use => Ok(CheckType::Use),
61+
CheckTypeProto::Generate => Ok(CheckType::Generate),
62+
CheckTypeProto::Import => Ok(CheckType::Import),
63+
CheckTypeProto::Derive => Ok(CheckType::Derive),
64+
}
65+
}
66+
}
67+
68+
// CheckType: from native to protobuf
69+
impl TryFrom<CheckType> for CheckTypeProto {
70+
type Error = ResponseStatus;
71+
72+
fn try_from(check_type_val: CheckType) -> std::result::Result<Self, Self::Error> {
73+
match check_type_val {
74+
CheckType::Use => Ok(CheckTypeProto::Use),
75+
CheckType::Generate => Ok(CheckTypeProto::Generate),
76+
CheckType::Import => Ok(CheckTypeProto::Import),
77+
CheckType::Derive => Ok(CheckTypeProto::Derive),
78+
}
79+
}
80+
}
81+
82+
// CheckType from protobuf to native
83+
pub fn i32_to_check_type(check_type_val: i32) -> std::result::Result<CheckType, ResponseStatus> {
84+
let check_type_proto: CheckTypeProto = check_type_val.try_into()?;
85+
check_type_proto.try_into()
86+
}
87+
88+
// CheckType from native to protobuf
89+
pub fn check_type_to_i32(check_type: CheckType) -> i32 {
90+
match check_type {
91+
CheckType::Use => CheckTypeProto::Use.into(),
92+
CheckType::Generate => CheckTypeProto::Generate.into(),
93+
CheckType::Import => CheckTypeProto::Import.into(),
94+
CheckType::Derive => CheckTypeProto::Derive.into(),
95+
}
96+
}
97+
98+
#[cfg(test)]
99+
mod test {
100+
101+
use super::super::generated_ops::can_do_crypto::Operation as OperationProto;
102+
use crate::operations::can_do_crypto::{CheckType, Operation};
103+
use crate::operations::psa_algorithm::{Algorithm, AsymmetricSignature, Hash};
104+
use crate::operations::psa_key_attributes::{self, Attributes, Lifetime, Policy, UsageFlags};
105+
use crate::operations_protobuf::convert_can_do_crypto::check_type_to_i32;
106+
use std::convert::TryInto;
107+
108+
#[test]
109+
fn proto_to_resp() {
110+
let mut usage_flags: UsageFlags = Default::default();
111+
let _ = usage_flags
112+
.set_export()
113+
.set_copy()
114+
.set_cache()
115+
.set_encrypt()
116+
.set_decrypt()
117+
.set_sign_message()
118+
.set_verify_message()
119+
.set_sign_hash()
120+
.set_verify_hash()
121+
.set_derive();
122+
let key_attrs = Attributes {
123+
lifetime: Lifetime::Persistent,
124+
key_type: psa_key_attributes::Type::RsaKeyPair,
125+
bits: 1024,
126+
policy: Policy {
127+
usage_flags,
128+
permitted_algorithms: Algorithm::AsymmetricSignature(
129+
AsymmetricSignature::RsaPkcs1v15Sign {
130+
hash_alg: Hash::Sha1.into(),
131+
},
132+
),
133+
},
134+
};
135+
let proto = OperationProto {
136+
check_type: check_type_to_i32(CheckType::Use),
137+
attributes: Some(key_attrs.try_into().expect("Failed conversion")),
138+
};
139+
140+
let resp: Operation = proto.try_into().expect("Failed conversion");
141+
142+
assert_eq!(resp.check_type, CheckType::Use);
143+
assert_eq!(resp.attributes, key_attrs);
144+
}
145+
146+
#[test]
147+
fn resp_to_proto() {
148+
let mut usage_flags: UsageFlags = Default::default();
149+
let _ = usage_flags
150+
.set_export()
151+
.set_copy()
152+
.set_cache()
153+
.set_encrypt()
154+
.set_decrypt()
155+
.set_sign_message()
156+
.set_verify_message()
157+
.set_sign_hash()
158+
.set_verify_hash()
159+
.set_derive();
160+
let key_attrs = Attributes {
161+
lifetime: Lifetime::Persistent,
162+
key_type: psa_key_attributes::Type::RsaKeyPair,
163+
bits: 1024,
164+
policy: Policy {
165+
usage_flags,
166+
permitted_algorithms: Algorithm::AsymmetricSignature(
167+
AsymmetricSignature::RsaPkcs1v15Sign {
168+
hash_alg: Hash::Sha1.into(),
169+
},
170+
),
171+
},
172+
};
173+
let resp: Operation = Operation {
174+
check_type: CheckType::Use,
175+
attributes: key_attrs,
176+
};
177+
178+
let proto: OperationProto = resp.try_into().expect("Failed conversion");
179+
180+
assert_eq!(proto.check_type, check_type_to_i32(CheckType::Use));
181+
assert_eq!(
182+
proto.attributes.expect("Failed conversion"),
183+
key_attrs.try_into().expect("Failed conversion")
184+
);
185+
}
186+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#[derive(Clone, PartialEq, ::prost::Message)]
2+
pub struct Operation {
3+
#[prost(enumeration="CheckType", tag="1")]
4+
pub check_type: i32,
5+
#[prost(message, optional, tag="2")]
6+
pub attributes: ::std::option::Option<super::psa_key_attributes::KeyAttributes>,
7+
}
8+
#[derive(Clone, PartialEq, ::prost::Message)]
9+
pub struct Result {
10+
}
11+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
12+
#[repr(i32)]
13+
pub enum CheckType {
14+
ChecktypeNone = 0,
15+
Use = 1,
16+
Generate = 2,
17+
Import = 3,
18+
Derive = 4,
19+
}

src/operations_protobuf/generated_ops/mod.rs

+17
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@ pub mod psa_generate_random;
2727
pub mod psa_hash_compute;
2828
pub mod psa_hash_compare;
2929
pub mod psa_raw_key_agreement;
30+
pub mod can_do_crypto;
3031

3132
use zeroize::Zeroize;
3233

3334
use crate::requests::{ResponseStatus, Result};
3435
use log::error;
3536
use psa_algorithm::algorithm::{aead::AeadWithDefaultLengthTag, key_agreement::Raw, Cipher, Hash};
3637
use psa_key_attributes::key_type::{DhFamily, EccFamily};
38+
use can_do_crypto::CheckType;
3739
use std::convert::TryFrom;
3840

3941
impl TryFrom<i32> for Cipher {
@@ -114,6 +116,19 @@ impl TryFrom<i32> for DhFamily {
114116
}
115117
}
116118

119+
impl TryFrom<i32> for CheckType {
120+
type Error = ResponseStatus;
121+
fn try_from(check_type_val: i32) -> Result<Self> {
122+
CheckType::from_i32(check_type_val).ok_or_else(|| {
123+
error!(
124+
"Value {} not supported as a check type.",
125+
check_type_val
126+
);
127+
ResponseStatus::InvalidEncoding
128+
})
129+
}
130+
}
131+
117132
pub(super) trait ClearProtoMessage {
118133
fn clear_message(&mut self) {}
119134
}
@@ -152,6 +167,8 @@ empty_clear_message!(psa_verify_hash::Result);
152167
empty_clear_message!(psa_verify_message::Result);
153168
empty_clear_message!(psa_generate_random::Operation);
154169
empty_clear_message!(psa_hash_compare::Result);
170+
empty_clear_message!(can_do_crypto::Operation);
171+
empty_clear_message!(can_do_crypto::Result);
155172

156173
impl ClearProtoMessage for psa_sign_hash::Operation {
157174
fn clear_message(&mut self) {

0 commit comments

Comments
 (0)