parsec_interface/operations_protobuf/
convert_psa_asymmetric_encrypt.rs1use super::generated_ops::psa_asymmetric_encrypt::{
4 Operation as OperationProto, Result as ResultProto,
5};
6use crate::operations::psa_asymmetric_encrypt::{Operation, Result};
7use crate::requests::ResponseStatus;
8use log::error;
9use std::convert::{TryFrom, TryInto};
10use zeroize::Zeroizing;
11
12impl TryFrom<OperationProto> for Operation {
13 type Error = ResponseStatus;
14
15 fn try_from(proto_op: OperationProto) -> std::result::Result<Self, Self::Error> {
16 let salt = match proto_op.salt.len() {
17 0 => None,
18 _ => Some(Zeroizing::new(proto_op.salt)),
19 };
20
21 Ok(Operation {
22 key_name: proto_op.key_name,
23 alg: proto_op
24 .alg
25 .ok_or_else(|| {
26 error!("The alg field of PsaAsymmetricEncrypt::Operation message is not set (mandatory field).");
27 ResponseStatus::InvalidEncoding
28 })?
29 .try_into()?,
30 plaintext: proto_op.plaintext.into(),
31 salt,
32 })
33 }
34}
35
36impl TryFrom<Operation> for OperationProto {
37 type Error = ResponseStatus;
38
39 fn try_from(op: Operation) -> std::result::Result<Self, Self::Error> {
40 let alg = Some(op.alg.try_into()?);
41 let salt = match op.salt {
42 Some(salt) => salt.to_vec(),
43 None => vec![],
44 };
45 Ok(OperationProto {
46 key_name: op.key_name,
47 alg,
48 plaintext: op.plaintext.to_vec(),
49 salt,
50 })
51 }
52}
53
54impl TryFrom<ResultProto> for Result {
55 type Error = ResponseStatus;
56
57 fn try_from(proto_result: ResultProto) -> std::result::Result<Self, Self::Error> {
58 Ok(Result {
59 ciphertext: proto_result.ciphertext.into(),
60 })
61 }
62}
63
64impl TryFrom<Result> for ResultProto {
65 type Error = ResponseStatus;
66
67 fn try_from(result: Result) -> std::result::Result<Self, Self::Error> {
68 Ok(ResultProto {
69 ciphertext: result.ciphertext.to_vec(),
70 })
71 }
72}
73
74#[cfg(test)]
75mod test {
76 use super::super::generated_ops::psa_algorithm as algorithm_proto;
77 use super::super::generated_ops::psa_asymmetric_encrypt::{
78 Operation as OperationProto, Result as ResultProto,
79 };
80 use super::super::{Convert, ProtobufConverter};
81 use crate::operations::psa_algorithm::AsymmetricEncryption;
82 use crate::operations::psa_asymmetric_encrypt::{Operation, Result};
83 use std::convert::TryInto;
84 static CONVERTER: ProtobufConverter = ProtobufConverter {};
85 use crate::operations::{NativeOperation, NativeResult};
86 use crate::requests::{request::RequestBody, response::ResponseBody, Opcode};
87
88 #[test]
89 fn asym_proto_to_op() {
90 let mut proto: OperationProto = Default::default();
91 let message = vec![0x11, 0x22, 0x33];
92 let key_name = "test name".to_string();
93 let salt: Vec<u8> = vec![];
94 proto.plaintext = message.clone();
95 proto.alg = Some(algorithm_proto::algorithm::AsymmetricEncryption {
96 variant: Some(
97 algorithm_proto::algorithm::asymmetric_encryption::Variant::RsaPkcs1v15Crypt(
98 algorithm_proto::algorithm::asymmetric_encryption::RsaPkcs1v15Crypt {},
99 ),
100 ),
101 });
102 proto.key_name = key_name.clone();
103 proto.salt = salt;
104
105 let op: Operation = proto.try_into().expect("Failed to convert");
106
107 assert_eq!(*op.plaintext, message);
108 assert_eq!(op.key_name, key_name);
109 assert_eq!(op.salt, None);
110 }
111
112 #[test]
113 fn asym_op_to_proto() {
114 let message = vec![0x11, 0x22, 0x33];
115 let key_name = "test name".to_string();
116
117 let op = Operation {
118 plaintext: message.clone().into(),
119 alg: AsymmetricEncryption::RsaPkcs1v15Crypt,
120 key_name: key_name.clone(),
121 salt: None,
122 };
123
124 let proto: OperationProto = op.try_into().expect("Failed to convert");
125
126 assert_eq!(proto.plaintext, message);
127 assert_eq!(proto.key_name, key_name);
128 assert_eq!(proto.salt, vec![]);
129 }
130
131 #[test]
132 fn asym_proto_to_resp() {
133 let mut proto: ResultProto = Default::default();
134 let ciphertext = vec![0x11, 0x22, 0x33];
135 proto.ciphertext = ciphertext.clone();
136
137 let result: Result = proto.try_into().expect("Failed to convert");
138
139 assert_eq!(*result.ciphertext, ciphertext);
140 }
141
142 #[test]
143 fn asym_resp_to_proto() {
144 let ciphertext = vec![0x11, 0x22, 0x33];
145 let result = Result {
146 ciphertext: ciphertext.clone().into(),
147 };
148
149 let proto: ResultProto = result.try_into().expect("Failed to convert");
150
151 assert_eq!(proto.ciphertext, ciphertext);
152 }
153
154 #[test]
155 fn psa_encrypt_message_op_e2e() {
156 let name = "test name".to_string();
157 let op = Operation {
158 key_name: name,
159 alg: AsymmetricEncryption::RsaPkcs1v15Crypt,
160 plaintext: vec![0x11, 0x22, 0x33].into(),
161 salt: None,
162 };
163
164 let body = CONVERTER
165 .operation_to_body(NativeOperation::PsaAsymmetricEncrypt(op))
166 .expect("Failed to convert to body");
167
168 let _ = CONVERTER
169 .body_to_operation(body, Opcode::PsaAsymmetricEncrypt)
170 .expect("Failed to convert to operation");
171 }
172
173 #[test]
174 fn resp_asym_encrypt_e2e() {
175 let result = Result {
176 ciphertext: vec![0x11, 0x22, 0x33].into(),
177 };
178 let body = CONVERTER
179 .result_to_body(NativeResult::PsaAsymmetricEncrypt(result))
180 .expect("Failed to convert request");
181
182 assert!(CONVERTER
183 .body_to_result(body, Opcode::PsaAsymmetricEncrypt)
184 .is_ok());
185 }
186
187 #[test]
188 fn result_from_mangled_resp_body() {
189 let resp_body =
190 ResponseBody::from_bytes(vec![0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]);
191 assert!(CONVERTER
192 .body_to_result(resp_body, Opcode::PsaAsymmetricEncrypt)
193 .is_err());
194 }
195
196 #[test]
197 fn op_from_mangled_req_body() {
198 let req_body =
199 RequestBody::from_bytes(vec![0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]);
200
201 assert!(CONVERTER
202 .body_to_operation(req_body, Opcode::PsaAsymmetricEncrypt)
203 .is_err());
204 }
205}