xref: /aosp_15_r20/system/secretkeeper/comm/tests/data_types.rs (revision 3f8e9d82f4020c68ad19a99fc5fdc1fc90b79379)
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 //! Unit tests for testing serialization & deserialization of exported data_types.
18 
19 use ciborium::Value;
20 use coset::CborSerializable;
21 use rdroidtest::rdroidtest;
22 use secretkeeper_comm::data_types::error::{Error, SecretkeeperError, ERROR_OK};
23 use secretkeeper_comm::data_types::packet::{RequestPacket, ResponsePacket, ResponseType};
24 use secretkeeper_comm::data_types::request::Request;
25 use secretkeeper_comm::data_types::request_response_impl::Opcode;
26 use secretkeeper_comm::data_types::request_response_impl::{
27     GetSecretRequest, GetSecretResponse, GetVersionRequest, GetVersionResponse, StoreSecretRequest,
28     StoreSecretResponse,
29 };
30 use secretkeeper_comm::data_types::response::Response;
31 use secretkeeper_comm::data_types::{Id, Secret, SeqNum};
32 
33 #[rdroidtest]
request_serialization_deserialization_get_version()34 fn request_serialization_deserialization_get_version() {
35     verify_request_structure(GetVersionRequest {}, Opcode::GetVersion);
36 }
37 
38 #[rdroidtest]
request_serialization_deserialization_store_secret()39 fn request_serialization_deserialization_store_secret() {
40     let req =
41         StoreSecretRequest { id: ex_id(), secret: ex_secret(), sealing_policy: ex_dice_policy() };
42     verify_request_structure(req, Opcode::StoreSecret);
43 }
44 
45 #[rdroidtest]
request_serialization_deserialization_get_secret()46 fn request_serialization_deserialization_get_secret() {
47     let req = GetSecretRequest { id: ex_id(), updated_sealing_policy: Some(ex_dice_policy()) };
48     verify_request_structure(req, Opcode::GetSecret);
49 
50     let req = GetSecretRequest { id: ex_id(), updated_sealing_policy: None };
51     verify_request_structure(req, Opcode::GetSecret);
52 }
53 
54 #[rdroidtest]
success_response_serialization_deserialization_get_version()55 fn success_response_serialization_deserialization_get_version() {
56     let response = GetVersionResponse { version: 1 };
57     verify_response_structure(response, ResponseType::Success);
58 }
59 
60 #[rdroidtest]
success_response_serialization_deserialization_store_secret()61 fn success_response_serialization_deserialization_store_secret() {
62     let response = StoreSecretResponse {};
63     verify_response_structure(response, ResponseType::Success);
64 }
65 
66 #[rdroidtest]
success_response_serialization_deserialization_get_secret()67 fn success_response_serialization_deserialization_get_secret() {
68     let response = GetSecretResponse { secret: ex_secret() };
69     verify_response_structure(response, ResponseType::Success);
70 }
71 
72 #[rdroidtest]
error_response_serialization_deserialization()73 fn error_response_serialization_deserialization() {
74     let response = SecretkeeperError::RequestMalformed;
75     verify_response_structure(response, ResponseType::Error);
76 }
77 
verify_request_structure<R: Request + core::fmt::Debug + core::cmp::PartialEq>( req: R, expected_opcode: Opcode, )78 fn verify_request_structure<R: Request + core::fmt::Debug + core::cmp::PartialEq>(
79     req: R,
80     expected_opcode: Opcode,
81 ) {
82     let packet = req.serialize_to_packet();
83     assert_eq!(packet.opcode().unwrap(), expected_opcode);
84     let packet = packet.to_vec().unwrap();
85     let packet = RequestPacket::from_slice(&packet).unwrap();
86     let req_other_end = *R::deserialize_from_packet(packet).unwrap();
87     assert_eq!(req, req_other_end);
88 }
89 
verify_response_structure<R: Response + core::fmt::Debug + core::cmp::PartialEq>( response: R, expected_response_type: ResponseType, )90 fn verify_response_structure<R: Response + core::fmt::Debug + core::cmp::PartialEq>(
91     response: R,
92     expected_response_type: ResponseType,
93 ) {
94     let packet = response.serialize_to_packet();
95     assert_eq!(packet.response_type().unwrap(), expected_response_type);
96     let packet_bytes = packet.to_vec().unwrap();
97     let packet = ResponsePacket::from_slice(&packet_bytes).unwrap();
98     let response_other_end = *R::deserialize_from_packet(packet).unwrap();
99     assert_eq!(response, response_other_end);
100 }
101 
102 #[rdroidtest]
request_creation()103 fn request_creation() {
104     // GetVersionRequest
105     let _: GetVersionRequest = *Request::new(vec![]).unwrap();
106 
107     // StoreSecretRequest
108     let req: StoreSecretRequest = *Request::new(vec![
109         Value::Bytes(ex_id_bytes()),
110         Value::Bytes(ex_secret_bytes()),
111         Value::Bytes(ex_dice_policy()),
112     ])
113     .unwrap();
114     assert_eq!(req.id.0, ex_id().0);
115     assert_eq!(req.secret.0, ex_secret().0);
116     assert_eq!(req.sealing_policy, ex_dice_policy());
117 
118     // GetSecretRequest with an updated_sealing_policy
119     let req: GetSecretRequest =
120         *Request::new(vec![Value::Bytes(ex_id_bytes()), Value::Bytes(ex_dice_policy())]).unwrap();
121     assert_eq!(req.id.0, ex_id().0);
122     assert_eq!(req.updated_sealing_policy, Some(ex_dice_policy()));
123 
124     // GetSecretRequest with no updated_sealing_policy
125     let req: GetSecretRequest =
126         *Request::new(vec![Value::Bytes(ex_id_bytes()), Value::Null]).unwrap();
127     assert_eq!(req.id.0, ex_id().0);
128     assert_eq!(req.updated_sealing_policy, None);
129 }
130 
131 #[rdroidtest]
response_creation()132 fn response_creation() {
133     // GetVersionResponse
134     let res: GetVersionResponse =
135         *Response::new(vec![Value::from(ERROR_OK), Value::from(5)]).unwrap();
136     assert_eq!(res.version, 5);
137 
138     // StoreSecretResponse
139     let _ = *<StoreSecretResponse as Response>::new(vec![Value::from(ERROR_OK)]).unwrap();
140 
141     // GetSecretResponse
142     let res = *<GetSecretResponse as Response>::new(vec![
143         Value::from(ERROR_OK),
144         Value::Bytes(ex_secret_bytes()),
145     ])
146     .unwrap();
147     assert_eq!(res.secret.0, ex_secret().0);
148 }
149 
150 #[rdroidtest]
invalid_request_creation()151 fn invalid_request_creation() {
152     // A GetVersionRequest with non-zero arg is invalid.
153     assert!(<GetVersionRequest as Request>::new(vec![Value::Null]).is_err());
154 
155     // StoreSecretRequest
156     // Incorrect number of arg is invalid.
157     assert!(<StoreSecretRequest as Request>::new(vec![]).is_err(),);
158     // Incorrect arg type is invalid.
159     assert!(<StoreSecretRequest as Request>::new(vec![
160         Value::Bytes(ex_id_bytes()),
161         Value::Integer(22.into()),
162         Value::Bytes(ex_dice_policy()),
163     ])
164     .is_err());
165 
166     // A GetSecretRequest
167     // Incorrect number of arg is invalid.
168     assert!(<GetSecretRequest as Request>::new(vec![]).is_err());
169     // Incorrect arg type is invalid.
170     assert!(<GetSecretRequest as Request>::new(vec![
171         Value::Integer(22.into()),
172         Value::Bytes(ex_dice_policy()),
173     ])
174     .is_err());
175 }
176 
177 #[rdroidtest]
invalid_response_creation_get_version()178 fn invalid_response_creation_get_version() {
179     // A response with non-zero error_code is an invalid success response.
180     assert!(<GetVersionResponse as Response>::new(vec![
181         Value::from(SecretkeeperError::RequestMalformed as u16),
182         Value::from(5)
183     ])
184     .is_err());
185 
186     // A response with incorrect size of array is invalid.
187     assert!(<GetVersionResponse as Response>::new(vec![
188         Value::from(ERROR_OK),
189         Value::from(5),
190         Value::from(7)
191     ])
192     .is_err());
193 
194     // A response with incorrect type is invalid.
195     assert!(<GetVersionResponse as Response>::new(vec![
196         Value::from(ERROR_OK),
197         Value::from("a tstr")
198     ])
199     .is_err());
200 }
201 
202 #[rdroidtest]
invalid_store_secret_response_creation()203 fn invalid_store_secret_response_creation() {
204     // A response with non-zero error_code is an invalid success response.
205     assert!(<StoreSecretResponse as Response>::new(vec![Value::from(
206         SecretkeeperError::RequestMalformed as u16
207     ),])
208     .is_err());
209 
210     // A response with incorrect type or size of array is invalid.
211     assert!(<StoreSecretResponse as Response>::new(vec![Value::from(ERROR_OK), Value::from(7)])
212         .is_err());
213 }
214 
215 #[rdroidtest]
invalid_get_secret_response_creation()216 fn invalid_get_secret_response_creation() {
217     // A response with non-zero error_code is an invalid success response.
218     assert!(<GetSecretResponse as Response>::new(vec![
219         Value::from(SecretkeeperError::RequestMalformed as u16),
220         Value::Bytes(ex_secret_bytes()),
221     ])
222     .is_err());
223 
224     // A response with incorrect type or size of array is invalid.
225     assert!(
226         <GetSecretResponse as Response>::new(vec![Value::from(ERROR_OK), Value::from(7)]).is_err()
227     );
228 }
229 
230 #[rdroidtest]
invalid_error_response_creation()231 fn invalid_error_response_creation() {
232     // A response with ERROR_OK(0) as the error_code is an invalid error response.
233     assert_eq!(
234         <SecretkeeperError as Response>::new(vec![Value::from(ERROR_OK)]).unwrap_err(),
235         Error::ResponseMalformed
236     );
237 }
238 
239 #[rdroidtest]
seq_num_test()240 fn seq_num_test() {
241     let mut seq_b = SeqNum::new();
242     let mut seq_a = SeqNum::new();
243     assert_eq!(seq_a.get_then_increment().unwrap(), seq_b.get_then_increment().unwrap());
244     let _ = seq_a.get_then_increment().unwrap();
245     assert_ne!(seq_a.get_then_increment().unwrap(), seq_b.get_then_increment().unwrap());
246     let _ = seq_b.get_then_increment().unwrap();
247     assert_eq!(seq_a.get_then_increment().unwrap(), seq_b.get_then_increment().unwrap());
248 }
249 
ex_id_bytes() -> Vec<u8>250 fn ex_id_bytes() -> Vec<u8> {
251     (b"sixty_four_bytes_in_a_sentences_can_make_it_really_really_longer").to_vec()
252 }
253 
ex_secret_bytes() -> Vec<u8>254 fn ex_secret_bytes() -> Vec<u8> {
255     (*b"thirty_two_bytes_long_sentences_").to_vec()
256 }
257 
ex_id() -> Id258 fn ex_id() -> Id {
259     Id(ex_id_bytes().try_into().unwrap())
260 }
261 
ex_secret() -> Secret262 fn ex_secret() -> Secret {
263     Secret(ex_secret_bytes().try_into().unwrap())
264 }
265 
ex_dice_policy() -> Vec<u8>266 fn ex_dice_policy() -> Vec<u8> {
267     (*b"example_dice_policy").to_vec()
268 }
269