• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //! Defines the shared behaviour of all response like data structures.
18 
19 use crate::data_types::error::{Error, ERROR_OK};
20 use crate::data_types::packet::ResponsePacket;
21 use alloc::boxed::Box;
22 use alloc::vec::Vec;
23 use ciborium::Value;
24 
25 /// Shared behaviour of all Secretkeeper's response-like data structures,
26 /// e.g. `GetVersionResponsePacket`. Note - A valid [`Response`] can be error as well, like
27 /// `SecretkeeperError::RequestMalformed`.
28 ///
29 /// Keep in sync with SecretManagement.cddl, in particular `ResponsePacket` type.
30 pub trait Response {
31     /// Constructor of the Response object.
32     /// # Arguments
33     /// * `response_cbor`: A vector of `[ciborium::Value]` such that:
34     /// ```
35     ///     For success-like responses:
36     ///         ResponsePacketSuccess = [
37     ///             0,                          ; Indicates successful Response
38     ///             result : Result
39     ///         ]
40     ///     For error responses:
41     ///         ResponsePacketError = [
42     ///             error_code: ErrorCode,      ; Indicate the error
43     ///             error_message: tstr         ; Additional human-readable context
44     ///         ]
45     /// ```
46     /// See `ResponsePacket<Result>` in SecretManagement.cddl alongside ISecretkeeper.aidl
new(response_cbor: Vec<Value>) -> Result<Box<Self>, Error>47     fn new(response_cbor: Vec<Value>) -> Result<Box<Self>, Error>;
48 
49     /// The result in the `Response`. By default this is empty, but [`Response`] structures like
50     /// `GetVersionResponse` must overwrite these to return the expected non-empty result.
result(&self) -> Vec<Value>51     fn result(&self) -> Vec<Value> {
52         Vec::new()
53     }
54 
55     /// Error code corresponding to the response. The default value is 0 but that will work only
56     /// for successful responses. Error-like response structures must overwrite this method.
error_code(&self) -> u1657     fn error_code(&self) -> u16 {
58         ERROR_OK // Indicates success
59     }
60 
61     /// Serialize the response to a [`ResponsePacket`].
serialize_to_packet(&self) -> ResponsePacket62     fn serialize_to_packet(&self) -> ResponsePacket {
63         let mut res = self.result();
64         res.insert(0, Value::from(self.error_code()));
65         ResponsePacket::from(res)
66     }
67 
68     /// Construct the response struct from given [`ResponsePacket`].
deserialize_from_packet(packet: ResponsePacket) -> Result<Box<Self>, Error>69     fn deserialize_from_packet(packet: ResponsePacket) -> Result<Box<Self>, Error> {
70         let res = packet.into_inner();
71         // Empty response packet is not allowed, all responses in Secretkeeper HAL at least
72         // have `error_code` or '0'; so throw an error!
73         if res.is_empty() {
74             return Err(Error::ResponseMalformed);
75         }
76         Self::new(res)
77     }
78 }
79