1use crate::authenticators::Application;
9use crate::providers::Provide;
10use derivative::Derivative;
11use log::{error, trace, warn};
12use parsec_interface::operations::Convert;
13use parsec_interface::operations::{NativeOperation, NativeResult};
14use parsec_interface::requests::{
15 request::RequestHeader, Request, Response, ResponseStatus, Result,
16};
17use parsec_interface::requests::{BodyType, ProviderId};
18use std::io::{Error, ErrorKind};
19use std::sync::Arc;
20
21#[derive(Derivative)]
29#[derivative(Debug)]
30pub struct BackEndHandler {
31 #[derivative(Debug = "ignore")]
33 provider: Arc<dyn Provide + Send + Sync>,
34 #[derivative(Debug = "ignore")]
35 converter: Box<dyn Convert + Send + Sync>,
36 provider_id: ProviderId,
37 content_type: BodyType,
38 accept_type: BodyType,
39}
40
41impl BackEndHandler {
42 fn result_to_response(&self, result: NativeResult, request_hdr: RequestHeader) -> Response {
44 let mut response = Response::from_request_header(request_hdr, ResponseStatus::Success);
45 match self.converter.result_to_body(result) {
46 Ok(body) => response.body = body,
47 Err(status) => response.header.status = status,
48 };
49 response
50 }
51
52 pub fn is_capable(&self, request: &Request) -> Result<()> {
62 let header = &request.header;
63
64 if (self.provider_id == ProviderId::Core) != header.opcode.is_core() {
65 error!("The request's operation is not compatible with the provider targeted.");
66 return Err(ResponseStatus::PsaErrorNotSupported);
67 }
68
69 if header.provider != self.provider_id {
70 Err(ResponseStatus::WrongProviderId)
71 } else if header.content_type != self.content_type {
72 Err(ResponseStatus::ContentTypeNotSupported)
73 } else if header.accept_type != self.accept_type {
74 Err(ResponseStatus::AcceptTypeNotSupported)
75 } else {
76 Ok(())
77 }
78 }
79
80 pub fn execute_request(&self, request: Request, app: Option<Application>) -> Response {
86 trace!("execute_request ingress");
87 let opcode = request.header.opcode;
88 let header = request.header;
89
90 macro_rules! unwrap_or_else_return {
91 ($result:expr) => {
92 match $result {
93 Ok(value) => value,
94 Err(status) => return Response::from_request_header(header, status),
95 }
96 };
97 }
98
99 if opcode.is_admin() {
100 let app = unwrap_or_else_return!(app.as_ref().ok_or(ResponseStatus::NotAuthenticated));
101
102 if !app.is_admin() {
103 warn!(
104 "Application name \"{}\" tried to perform an admin operation ({:?}).",
105 app.identity().name(),
106 opcode
107 );
108 return Response::from_request_header(header, ResponseStatus::AdminOperation);
109 }
110 }
111
112 match unwrap_or_else_return!(self.converter.body_to_operation(request.body, opcode)) {
113 NativeOperation::ListProviders(op_list_providers) => {
114 let result =
115 unwrap_or_else_return!(self.provider.list_providers(op_list_providers));
116 trace!("list_providers egress");
117 self.result_to_response(NativeResult::ListProviders(result), header)
118 }
119 NativeOperation::ListOpcodes(op_list_opcodes) => {
120 let result = unwrap_or_else_return!(self.provider.list_opcodes(op_list_opcodes));
121 trace!("list_opcodes egress");
122 self.result_to_response(NativeResult::ListOpcodes(result), header)
123 }
124 NativeOperation::Ping(op_ping) => {
125 let result = unwrap_or_else_return!(self.provider.ping(op_ping));
126 trace!("ping egress");
127 self.result_to_response(NativeResult::Ping(result), header)
128 }
129 NativeOperation::PsaGenerateKey(op_generate_key) => {
130 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
131 let result = unwrap_or_else_return!(self
132 .provider
133 .psa_generate_key(app.identity(), op_generate_key));
134 trace!("psa_generate_key egress");
135 self.result_to_response(NativeResult::PsaGenerateKey(result), header)
136 }
137 NativeOperation::PsaImportKey(op_import_key) => {
138 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
139 let result = unwrap_or_else_return!(self
140 .provider
141 .psa_import_key(app.identity(), op_import_key));
142 trace!("psa_import_key egress");
143 self.result_to_response(NativeResult::PsaImportKey(result), header)
144 }
145 NativeOperation::PsaExportPublicKey(op_export_public_key) => {
146 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
147 let result = unwrap_or_else_return!(self
148 .provider
149 .psa_export_public_key(app.identity(), op_export_public_key));
150 trace!("psa_export_public_key egress");
151 self.result_to_response(NativeResult::PsaExportPublicKey(result), header)
152 }
153 NativeOperation::PsaExportKey(op_export_key) => {
154 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
155 let result = unwrap_or_else_return!(self
156 .provider
157 .psa_export_key(app.identity(), op_export_key));
158 trace!("psa_export_key egress");
159 self.result_to_response(NativeResult::PsaExportKey(result), header)
160 }
161 NativeOperation::PsaDestroyKey(op_destroy_key) => {
162 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
163 let result = unwrap_or_else_return!(self
164 .provider
165 .psa_destroy_key(app.identity(), op_destroy_key));
166 trace!("psa_destroy_key egress");
167 self.result_to_response(NativeResult::PsaDestroyKey(result), header)
168 }
169 NativeOperation::PsaSignHash(op_sign_hash) => {
170 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
171 let result = unwrap_or_else_return!(self
172 .provider
173 .psa_sign_hash(app.identity(), op_sign_hash));
174 trace!("psa_sign_hash egress");
175 self.result_to_response(NativeResult::PsaSignHash(result), header)
176 }
177 NativeOperation::PsaVerifyHash(op_verify_hash) => {
178 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
179 let result = unwrap_or_else_return!(self
180 .provider
181 .psa_verify_hash(app.identity(), op_verify_hash));
182 trace!("psa_verify_hash egress");
183 self.result_to_response(NativeResult::PsaVerifyHash(result), header)
184 }
185 NativeOperation::PsaAsymmetricEncrypt(op_asymmetric_encrypt) => {
186 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
187 let result = unwrap_or_else_return!(self
188 .provider
189 .psa_asymmetric_encrypt(app.identity(), op_asymmetric_encrypt));
190 trace!("psa_asymmetric_encrypt egress");
191 self.result_to_response(NativeResult::PsaAsymmetricEncrypt(result), header)
192 }
193 NativeOperation::PsaAsymmetricDecrypt(op_asymmetric_decrypt) => {
194 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
195 let result = unwrap_or_else_return!(self
196 .provider
197 .psa_asymmetric_decrypt(app.identity(), op_asymmetric_decrypt));
198 trace!("psa_asymmetric_decrypt egress");
199 self.result_to_response(NativeResult::PsaAsymmetricDecrypt(result), header)
200 }
201 NativeOperation::PsaAeadEncrypt(op_aead_encrypt) => {
202 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
203 let result = unwrap_or_else_return!(self
204 .provider
205 .psa_aead_encrypt(app.identity(), op_aead_encrypt));
206 trace!("psa_aead_encrypt egress");
207 self.result_to_response(NativeResult::PsaAeadEncrypt(result), header)
208 }
209 NativeOperation::PsaAeadDecrypt(op_aead_decrypt) => {
210 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
211 let result = unwrap_or_else_return!(self
212 .provider
213 .psa_aead_decrypt(app.identity(), op_aead_decrypt));
214 trace!("psa_aead_decrypt egress");
215 self.result_to_response(NativeResult::PsaAeadDecrypt(result), header)
216 }
217 NativeOperation::ListAuthenticators(op_list_authenticators) => {
218 let result = unwrap_or_else_return!(self
219 .provider
220 .list_authenticators(op_list_authenticators));
221 trace!("list_authenticators egress");
222 self.result_to_response(NativeResult::ListAuthenticators(result), header)
223 }
224 NativeOperation::ListKeys(op_list_keys) => {
225 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
226 let result =
227 unwrap_or_else_return!(self.provider.list_keys(app.identity(), op_list_keys));
228 trace!("list_keys egress");
229 self.result_to_response(NativeResult::ListKeys(result), header)
230 }
231 NativeOperation::ListClients(op_list_clients) => {
232 let result = unwrap_or_else_return!(self.provider.list_clients(op_list_clients));
233 trace!("list_clients egress");
234 self.result_to_response(NativeResult::ListClients(result), header)
235 }
236 NativeOperation::DeleteClient(op_delete_client) => {
237 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
238 let result = unwrap_or_else_return!(self
239 .provider
240 .delete_client(app.identity(), op_delete_client));
241 trace!("delete_client egress");
242 self.result_to_response(NativeResult::DeleteClient(result), header)
243 }
244 NativeOperation::PsaHashCompute(op_hash_compute) => {
245 let result =
246 unwrap_or_else_return!(self.provider.psa_hash_compute(op_hash_compute));
247 trace!("psa_hash_compute egress");
248 self.result_to_response(NativeResult::PsaHashCompute(result), header)
249 }
250 NativeOperation::PsaHashCompare(op_hash_compare) => {
251 let result =
252 unwrap_or_else_return!(self.provider.psa_hash_compare(op_hash_compare));
253 trace!("psa_hash_compare egress");
254 self.result_to_response(NativeResult::PsaHashCompare(result), header)
255 }
256 NativeOperation::PsaRawKeyAgreement(op_raw_key_agreement) => {
257 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
258 let result = unwrap_or_else_return!(self
259 .provider
260 .psa_raw_key_agreement(app.identity(), op_raw_key_agreement));
261 trace!("psa_raw_key_agreement egress");
262 self.result_to_response(NativeResult::PsaRawKeyAgreement(result), header)
263 }
264 NativeOperation::PsaGenerateRandom(op_generate_random) => {
265 let result =
266 unwrap_or_else_return!(self.provider.psa_generate_random(op_generate_random));
267 trace!("psa_generate_random egress");
268 self.result_to_response(NativeResult::PsaGenerateRandom(result), header)
269 }
270 NativeOperation::PsaSignMessage(op_sign_message) => {
271 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
272 let result = unwrap_or_else_return!(self
273 .provider
274 .psa_sign_message(app.identity(), op_sign_message));
275 trace!("psa_sign_message egress");
276 self.result_to_response(NativeResult::PsaSignMessage(result), header)
277 }
278 NativeOperation::PsaVerifyMessage(op_verify_message) => {
279 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
280 let result = unwrap_or_else_return!(self
281 .provider
282 .psa_verify_message(app.identity(), op_verify_message));
283 trace!("psa_verify_message egress");
284 self.result_to_response(NativeResult::PsaVerifyMessage(result), header)
285 }
286 NativeOperation::PsaCipherEncrypt(op_cipher_encrypt) => {
287 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
288 let result = unwrap_or_else_return!(self
289 .provider
290 .psa_cipher_encrypt(app.identity(), op_cipher_encrypt));
291 trace!("op_cipher_encrypt egress");
292 self.result_to_response(NativeResult::PsaCipherEncrypt(result), header)
293 }
294 NativeOperation::PsaCipherDecrypt(op_cipher_decrypt) => {
295 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
296 let result = unwrap_or_else_return!(self
297 .provider
298 .psa_cipher_decrypt(app.identity(), op_cipher_decrypt));
299 trace!("psa_cipher_decrypt egress");
300 self.result_to_response(NativeResult::PsaCipherDecrypt(result), header)
301 }
302 NativeOperation::CanDoCrypto(op_can_do_crypto) => {
303 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
304 let result = unwrap_or_else_return!(self
305 .provider
306 .can_do_crypto(app.identity(), op_can_do_crypto));
307 trace!("can_do_crypto egress");
308 self.result_to_response(NativeResult::CanDoCrypto(result), header)
309 }
310 NativeOperation::PrepareKeyAttestation(op_prepare_key_attestation) => {
311 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
312 let result = unwrap_or_else_return!(self
313 .provider
314 .prepare_key_attestation(app.identity(), op_prepare_key_attestation));
315 trace!("prepare_key_attestation egress");
316 self.result_to_response(NativeResult::PrepareKeyAttestation(result), header)
317 }
318 NativeOperation::AttestKey(op_attest_key) => {
319 let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated));
320 let result =
321 unwrap_or_else_return!(self.provider.attest_key(app.identity(), op_attest_key));
322 trace!("attest_key egress");
323 self.result_to_response(NativeResult::AttestKey(result), header)
324 }
325 }
326 }
327}
328
329#[derive(Default, Derivative)]
331#[derivative(Debug)]
332pub struct BackEndHandlerBuilder {
333 #[derivative(Debug = "ignore")]
334 provider: Option<Arc<dyn Provide + Send + Sync>>,
335 #[derivative(Debug = "ignore")]
336 converter: Option<Box<dyn Convert + Send + Sync>>,
337 provider_id: Option<ProviderId>,
338 content_type: Option<BodyType>,
339 accept_type: Option<BodyType>,
340}
341
342impl BackEndHandlerBuilder {
343 pub fn new() -> BackEndHandlerBuilder {
345 BackEndHandlerBuilder {
346 provider: None,
347 converter: None,
348 provider_id: None,
349 content_type: None,
350 accept_type: None,
351 }
352 }
353
354 pub fn with_provider(mut self, provider: Arc<dyn Provide + Send + Sync>) -> Self {
356 self.provider = Some(provider);
357 self
358 }
359
360 pub fn with_converter(mut self, converter: Box<dyn Convert + Send + Sync>) -> Self {
362 self.converter = Some(converter);
363 self
364 }
365
366 pub fn with_provider_id(mut self, provider_id: ProviderId) -> Self {
368 self.provider_id = Some(provider_id);
369 self
370 }
371
372 pub fn with_content_type(mut self, content_type: BodyType) -> Self {
374 self.content_type = Some(content_type);
375 self
376 }
377
378 pub fn with_accept_type(mut self, accept_type: BodyType) -> Self {
380 self.accept_type = Some(accept_type);
381 self
382 }
383
384 pub fn build(self) -> std::io::Result<BackEndHandler> {
386 Ok(BackEndHandler {
387 provider: self
388 .provider
389 .ok_or_else(|| Error::new(ErrorKind::InvalidData, "provider is missing"))?,
390 converter: self
391 .converter
392 .ok_or_else(|| Error::new(ErrorKind::InvalidData, "converter is missing"))?,
393 provider_id: self
394 .provider_id
395 .ok_or_else(|| Error::new(ErrorKind::InvalidData, "provider_id is missing"))?,
396 content_type: self
397 .content_type
398 .ok_or_else(|| Error::new(ErrorKind::InvalidData, "content_type is missing"))?,
399 accept_type: self
400 .accept_type
401 .ok_or_else(|| Error::new(ErrorKind::InvalidData, "accept_type is missing"))?,
402 })
403 }
404}