parsec_interface/operations_protobuf/
convert_psa_generate_key.rs

1// Copyright 2019 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use super::generated_ops::psa_generate_key::{Operation as OperationProto, Result as ResultProto};
4use crate::operations::psa_generate_key::{Operation, Result};
5use crate::requests::ResponseStatus;
6use log::error;
7use std::convert::{TryFrom, TryInto};
8
9impl TryFrom<OperationProto> for Operation {
10    type Error = ResponseStatus;
11
12    fn try_from(proto_op: OperationProto) -> std::result::Result<Self, Self::Error> {
13        Ok(Operation {
14            key_name: proto_op.key_name,
15            attributes: proto_op
16                .attributes
17                .ok_or_else(|| {
18                    error!("The attributes field of PsaGenerateKey::Operation message is not set (mandatory field).");
19                    ResponseStatus::InvalidEncoding
20                })?
21                .try_into()?,
22        })
23    }
24}
25
26impl TryFrom<Operation> for OperationProto {
27    type Error = ResponseStatus;
28
29    fn try_from(op: Operation) -> std::result::Result<Self, Self::Error> {
30        let proto = OperationProto {
31            key_name: op.key_name,
32            attributes: Some(op.attributes.try_into()?),
33        };
34
35        Ok(proto)
36    }
37}
38
39impl TryFrom<Result> for ResultProto {
40    type Error = ResponseStatus;
41
42    fn try_from(_result: Result) -> std::result::Result<Self, Self::Error> {
43        Ok(Default::default())
44    }
45}
46
47impl TryFrom<ResultProto> for Result {
48    type Error = ResponseStatus;
49
50    fn try_from(_response: ResultProto) -> std::result::Result<Self, Self::Error> {
51        Ok(Result {})
52    }
53}
54
55#[cfg(test)]
56mod test {
57    #![allow(deprecated)]
58    use super::super::generated_ops::psa_algorithm::{
59        self as algorithm_proto, Algorithm as AlgorithmProto,
60    };
61    use super::super::generated_ops::psa_generate_key::{
62        Operation as OperationProto, Result as ResultProto,
63    };
64    use super::super::generated_ops::psa_key_attributes::{
65        self as key_attributes_proto, KeyAttributes as KeyAttributesProto,
66    };
67    use super::super::{Convert, ProtobufConverter};
68    use crate::operations::psa_algorithm::{Algorithm, AsymmetricSignature, Hash};
69    use crate::operations::psa_generate_key::{Operation, Result};
70    use crate::operations::psa_key_attributes::{self, Attributes, Lifetime, Policy, UsageFlags};
71    use crate::operations::NativeOperation;
72    use crate::requests::Opcode;
73    use std::convert::TryInto;
74
75    static CONVERTER: ProtobufConverter = ProtobufConverter {};
76
77    #[test]
78    fn create_key_op_from_proto() {
79        let name = "test name".to_string();
80        let proto = OperationProto {
81            key_name: name.clone(),
82            attributes: Some(get_key_attrs_proto()),
83        };
84
85        let op: Operation = proto.try_into().expect("Failed conversion");
86        assert_eq!(op.key_name, name);
87    }
88
89    #[test]
90    fn create_key_op_to_proto() {
91        let name = "test name".to_string();
92        let op = Operation {
93            key_name: name.clone(),
94            attributes: get_key_attrs(),
95        };
96
97        let proto: OperationProto = op.try_into().expect("Failed conversion");
98        assert_eq!(proto.key_name, name);
99    }
100
101    #[test]
102    fn create_key_res_from_proto() {
103        let proto = ResultProto {};
104        let _res: Result = proto.try_into().expect("Failed conversion");
105    }
106
107    #[test]
108    fn create_key_res_to_proto() {
109        let res = Result {};
110        let _proto: ResultProto = res.try_into().expect("Failed conversion");
111    }
112
113    #[test]
114    fn create_key_op_e2e() {
115        let name = "test name".to_string();
116        let op = Operation {
117            key_name: name,
118            attributes: get_key_attrs(),
119        };
120
121        let body = CONVERTER
122            .operation_to_body(NativeOperation::PsaGenerateKey(op))
123            .expect("Failed to convert to body");
124
125        let _ = CONVERTER
126            .body_to_operation(body, Opcode::PsaGenerateKey)
127            .expect("Failed to convert to operation");
128    }
129
130    fn get_key_attrs() -> Attributes {
131        let mut usage_flags = UsageFlags::default();
132        let _ = usage_flags
133            .set_decrypt()
134            .set_export()
135            .set_copy()
136            .set_cache()
137            .set_encrypt()
138            .set_decrypt()
139            .set_sign_message()
140            .set_verify_message()
141            .set_sign_hash()
142            .set_verify_hash()
143            .set_derive();
144        Attributes {
145            lifetime: Lifetime::Persistent,
146            key_type: psa_key_attributes::Type::RsaKeyPair,
147            bits: 1024,
148            policy: Policy {
149                usage_flags,
150                permitted_algorithms: Algorithm::AsymmetricSignature(
151                    AsymmetricSignature::RsaPkcs1v15Sign {
152                        hash_alg: Hash::Sha1.into(),
153                    },
154                ),
155            },
156        }
157    }
158
159    fn get_key_attrs_proto() -> KeyAttributesProto {
160        KeyAttributesProto {
161            key_type: Some(key_attributes_proto::KeyType {
162                variant: Some(key_attributes_proto::key_type::Variant::RsaKeyPair(key_attributes_proto::key_type::RsaKeyPair {})),
163            }),
164            key_bits: 1024,
165            key_policy: Some(key_attributes_proto::KeyPolicy {
166                key_usage_flags: Some(key_attributes_proto::UsageFlags {
167                    export: true,
168                    copy: true,
169                    cache: true,
170                    encrypt: true,
171                    decrypt: true,
172                    sign_message: true,
173                    verify_message: true,
174                    sign_hash: true,
175                    verify_hash: true,
176                    derive: true,
177                }),
178                key_algorithm: Some(AlgorithmProto {
179                    variant: Some(algorithm_proto::algorithm::Variant::AsymmetricSignature(algorithm_proto::algorithm::AsymmetricSignature {
180                        variant: Some(algorithm_proto::algorithm::asymmetric_signature::Variant::RsaPkcs1v15Sign(algorithm_proto::algorithm::asymmetric_signature::RsaPkcs1v15Sign {
181                            hash_alg: Some(algorithm_proto::algorithm::asymmetric_signature::SignHash {
182                                variant: Some(algorithm_proto::algorithm::asymmetric_signature::sign_hash::Variant::Specific(
183                                    algorithm_proto::algorithm::Hash::Sha1.into(),
184                                )),
185                            }),
186                        })),
187                    }))
188                }),
189            }),
190        }
191    }
192}