parsec_interface/operations_protobuf/
convert_prepare_key_attestation.rs

1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use super::generated_ops::prepare_key_attestation::{
4    prepare_key_attestation_output, prepare_key_attestation_params, Operation as OperationProto,
5    PrepareKeyAttestationOutput, PrepareKeyAttestationParams, Result as ResultProto,
6};
7use crate::operations::prepare_key_attestation::{Operation, Result};
8use crate::requests::ResponseStatus;
9use log::error;
10use std::convert::TryFrom;
11
12impl TryFrom<Operation> for OperationProto {
13    type Error = ResponseStatus;
14
15    fn try_from(op: Operation) -> std::result::Result<Self, Self::Error> {
16        match op {
17            Operation::ActivateCredential {
18                attested_key_name,
19                attesting_key_name,
20            } => Ok(OperationProto {
21                parameters: Some(PrepareKeyAttestationParams {
22                    mechanism: Some(
23                        prepare_key_attestation_params::Mechanism::ActivateCredential(
24                            prepare_key_attestation_params::ActivateCredential {
25                                attested_key_name,
26                                attesting_key_name: attesting_key_name.unwrap_or_default(),
27                            },
28                        ),
29                    ),
30                }),
31            }),
32        }
33    }
34}
35
36impl TryFrom<OperationProto> for Operation {
37    type Error = ResponseStatus;
38
39    fn try_from(op: OperationProto) -> std::result::Result<Self, Self::Error> {
40        match op {
41            OperationProto {
42                parameters:
43                    Some(PrepareKeyAttestationParams {
44                        mechanism:
45                            Some(prepare_key_attestation_params::Mechanism::ActivateCredential(
46                                prepare_key_attestation_params::ActivateCredential {
47                                    attested_key_name,
48                                    attesting_key_name,
49                                },
50                            )),
51                    }),
52            } => Ok(Operation::ActivateCredential {
53                attested_key_name,
54                attesting_key_name: if attesting_key_name.is_empty() {
55                    None
56                } else {
57                    Some(attesting_key_name)
58                },
59            }),
60            _ => {
61                error!("The encoding of the operation does not follow the expected pattern");
62                Err(ResponseStatus::InvalidEncoding)
63            }
64        }
65    }
66}
67
68impl TryFrom<Result> for ResultProto {
69    type Error = ResponseStatus;
70
71    fn try_from(op: Result) -> std::result::Result<Self, Self::Error> {
72        match op {
73            Result::ActivateCredential {
74                name,
75                public,
76                attesting_key_pub,
77            } => Ok(ResultProto {
78                output: Some(PrepareKeyAttestationOutput {
79                    mechanism: Some(
80                        prepare_key_attestation_output::Mechanism::ActivateCredential(
81                            prepare_key_attestation_output::ActivateCredential {
82                                name: name.to_vec(),
83                                public: public.to_vec(),
84                                attesting_key_pub: attesting_key_pub.to_vec(),
85                            },
86                        ),
87                    ),
88                }),
89            }),
90        }
91    }
92}
93
94impl TryFrom<ResultProto> for Result {
95    type Error = ResponseStatus;
96
97    fn try_from(op: ResultProto) -> std::result::Result<Self, Self::Error> {
98        match op {
99            ResultProto {
100                output:
101                    Some(PrepareKeyAttestationOutput {
102                        mechanism:
103                            Some(prepare_key_attestation_output::Mechanism::ActivateCredential(
104                                prepare_key_attestation_output::ActivateCredential {
105                                    name,
106                                    public,
107                                    attesting_key_pub,
108                                },
109                            )),
110                    }),
111            } => Ok(Result::ActivateCredential {
112                name: name.into(),
113                public: public.into(),
114                attesting_key_pub: attesting_key_pub.into(),
115            }),
116            _ => {
117                error!("The encoding of the operation does not follow the expected pattern");
118                Err(ResponseStatus::InvalidEncoding)
119            }
120        }
121    }
122}
123
124#[cfg(test)]
125mod test {
126    use super::super::generated_ops::prepare_key_attestation::{
127        prepare_key_attestation_output, prepare_key_attestation_params,
128        Operation as OperationProto, PrepareKeyAttestationOutput, PrepareKeyAttestationParams,
129        Result as ResultProto,
130    };
131    use super::super::{Convert, ProtobufConverter};
132    use crate::operations::{
133        prepare_key_attestation::Operation, prepare_key_attestation::Result, NativeOperation,
134        NativeResult,
135    };
136    use crate::requests::Opcode;
137    use std::convert::TryInto;
138
139    static CONVERTER: ProtobufConverter = ProtobufConverter {};
140
141    #[test]
142    fn prepare_key_attestation_op_from_proto() {
143        let op_attested_key_name = String::from("attested key name");
144        let op_attesting_key_name = String::from("attesting key name");
145
146        let proto = OperationProto {
147            parameters: Some(PrepareKeyAttestationParams {
148                mechanism: Some(
149                    prepare_key_attestation_params::Mechanism::ActivateCredential(
150                        prepare_key_attestation_params::ActivateCredential {
151                            attested_key_name: op_attested_key_name.clone(),
152                            attesting_key_name: op_attesting_key_name.clone(),
153                        },
154                    ),
155                ),
156            }),
157        };
158
159        let op: Operation = proto.try_into().expect("Conversion failed");
160
161        let Operation::ActivateCredential {
162            attested_key_name,
163            attesting_key_name,
164        } = op;
165
166        assert_eq!(attested_key_name, op_attested_key_name);
167        assert_eq!(
168            attesting_key_name.expect("Attesting key name was empty"),
169            op_attesting_key_name
170        );
171    }
172
173    #[test]
174    fn prepare_key_attestation_proto_no_attesting() {
175        let op_attested_key_name = String::from("attested key name");
176
177        let proto = OperationProto {
178            parameters: Some(PrepareKeyAttestationParams {
179                mechanism: Some(
180                    prepare_key_attestation_params::Mechanism::ActivateCredential(
181                        prepare_key_attestation_params::ActivateCredential {
182                            attested_key_name: op_attested_key_name,
183                            attesting_key_name: String::new(),
184                        },
185                    ),
186                ),
187            }),
188        };
189
190        let op: Operation = proto.try_into().expect("Conversion failed");
191
192        let Operation::ActivateCredential {
193            attesting_key_name, ..
194        } = op;
195
196        assert!(attesting_key_name.is_none());
197    }
198
199    #[test]
200    fn prepare_key_attestation_op_to_proto() {
201        let op_attested_key_name = String::from("attested key name");
202        let op_attesting_key_name = String::from("attesting key name");
203
204        let op: Operation = Operation::ActivateCredential {
205            attested_key_name: op_attested_key_name.clone(),
206            attesting_key_name: Some(op_attesting_key_name.clone()),
207        };
208
209        let proto: OperationProto = op.try_into().expect("Conversion failed");
210
211        if let OperationProto {
212            parameters:
213                Some(PrepareKeyAttestationParams {
214                    mechanism:
215                        Some(prepare_key_attestation_params::Mechanism::ActivateCredential(
216                            prepare_key_attestation_params::ActivateCredential {
217                                attested_key_name,
218                                attesting_key_name,
219                            },
220                        )),
221                }),
222        } = proto
223        {
224            assert_eq!(attested_key_name, op_attested_key_name);
225            assert_eq!(attesting_key_name, op_attesting_key_name);
226        }
227    }
228
229    #[test]
230    fn prepare_key_attestation_op_no_attesting() {
231        let op_attested_key_name = String::from("attested key name");
232
233        let op: Operation = Operation::ActivateCredential {
234            attested_key_name: op_attested_key_name,
235            attesting_key_name: None,
236        };
237
238        let proto: OperationProto = op.try_into().expect("Conversion failed");
239
240        if let OperationProto {
241            parameters:
242                Some(PrepareKeyAttestationParams {
243                    mechanism:
244                        Some(prepare_key_attestation_params::Mechanism::ActivateCredential(
245                            prepare_key_attestation_params::ActivateCredential {
246                                attesting_key_name,
247                                ..
248                            },
249                        )),
250                }),
251        } = proto
252        {
253            assert_eq!(attesting_key_name, String::new());
254        }
255    }
256
257    #[test]
258    fn prepare_key_attestation_op_e2e() {
259        let op_attested_key_name = String::from("attested key name");
260        let op_attesting_key_name = String::from("attesting key name");
261
262        let op: Operation = Operation::ActivateCredential {
263            attested_key_name: op_attested_key_name,
264            attesting_key_name: Some(op_attesting_key_name),
265        };
266
267        let body = CONVERTER
268            .operation_to_body(NativeOperation::PrepareKeyAttestation(op))
269            .expect("Failed to convert to body");
270
271        let _ = CONVERTER
272            .body_to_operation(body, Opcode::PrepareKeyAttestation)
273            .expect("Failed to convert to operation");
274    }
275
276    #[test]
277    fn prepare_key_attestation_resp_to_proto() {
278        let resp_name = vec![0xff; 32];
279        let resp_public = vec![0xcc; 32];
280        let resp_attesting_key_pub = vec![0x22; 32];
281
282        let result = Result::ActivateCredential {
283            name: resp_name.clone().into(),
284            public: resp_public.clone().into(),
285            attesting_key_pub: resp_attesting_key_pub.clone().into(),
286        };
287
288        let proto: ResultProto = result.try_into().expect("Conversion failed");
289        if let ResultProto {
290            output:
291                Some(PrepareKeyAttestationOutput {
292                    mechanism:
293                        Some(prepare_key_attestation_output::Mechanism::ActivateCredential(
294                            prepare_key_attestation_output::ActivateCredential {
295                                name,
296                                public,
297                                attesting_key_pub,
298                            },
299                        )),
300                }),
301        } = proto
302        {
303            assert_eq!(name, resp_name);
304            assert_eq!(public, resp_public);
305            assert_eq!(attesting_key_pub, resp_attesting_key_pub);
306        }
307    }
308
309    #[test]
310    fn prepare_key_attestation_resp_from_proto() {
311        let resp_name = vec![0xff; 32];
312        let resp_public = vec![0xcc; 32];
313        let resp_attesting_key_pub = vec![0x22; 32];
314
315        let proto = ResultProto {
316            output: Some(PrepareKeyAttestationOutput {
317                mechanism: Some(
318                    prepare_key_attestation_output::Mechanism::ActivateCredential(
319                        prepare_key_attestation_output::ActivateCredential {
320                            name: resp_name.clone(),
321                            public: resp_public.clone(),
322                            attesting_key_pub: resp_attesting_key_pub.clone(),
323                        },
324                    ),
325                ),
326            }),
327        };
328
329        let result: Result = proto.try_into().expect("Conversion failed");
330
331        let Result::ActivateCredential {
332            name,
333            public,
334            attesting_key_pub,
335        } = result;
336
337        assert_eq!(name.to_vec(), resp_name);
338        assert_eq!(public.to_vec(), resp_public);
339        assert_eq!(attesting_key_pub.to_vec(), resp_attesting_key_pub);
340    }
341
342    #[test]
343    fn prepare_key_attestation_resp_e2e() {
344        let resp_name = vec![0xff; 32];
345        let resp_public = vec![0xcc; 32];
346        let resp_attesting_key_pub = vec![0x22; 32];
347
348        let result = Result::ActivateCredential {
349            name: resp_name.into(),
350            public: resp_public.into(),
351            attesting_key_pub: resp_attesting_key_pub.into(),
352        };
353
354        let body = CONVERTER
355            .result_to_body(NativeResult::PrepareKeyAttestation(result))
356            .expect("Failed to convert to body");
357
358        let _ = CONVERTER
359            .body_to_result(body, Opcode::PrepareKeyAttestation)
360            .expect("Failed to convert to operation");
361    }
362}