|
| 1 | +// Copyright 2021 Contributors to the Parsec project. |
| 2 | +// SPDX-License-Identifier: Apache-2.0 |
| 3 | +use super::generated_ops::can_do_crypto::{ |
| 4 | + CheckType as CheckTypeProto, Operation as OperationProto, Result as ResultProto, |
| 5 | +}; |
| 6 | +use crate::operations::can_do_crypto::{CheckType, Operation, Result}; |
| 7 | +use crate::requests::ResponseStatus; |
| 8 | +use log::error; |
| 9 | +use std::convert::{TryFrom, TryInto}; |
| 10 | + |
| 11 | +impl TryFrom<OperationProto> for Operation { |
| 12 | + type Error = ResponseStatus; |
| 13 | + |
| 14 | + fn try_from(proto_op: OperationProto) -> std::result::Result<Self, Self::Error> { |
| 15 | + let key_attributes = proto_op.attributes.ok_or_else(|| { |
| 16 | + error!("The attributes field of CanDoCrypto::Operation message is not set (mandatory field)."); |
| 17 | + ResponseStatus::InvalidEncoding |
| 18 | + })?; |
| 19 | + Ok(Operation { |
| 20 | + check_type: i32_to_check_type(proto_op.check_type)?, |
| 21 | + attributes: key_attributes.try_into()?, |
| 22 | + }) |
| 23 | + } |
| 24 | +} |
| 25 | + |
| 26 | +impl TryFrom<Operation> for OperationProto { |
| 27 | + type Error = ResponseStatus; |
| 28 | + |
| 29 | + fn try_from(op: Operation) -> std::result::Result<Self, Self::Error> { |
| 30 | + Ok(OperationProto { |
| 31 | + check_type: check_type_to_i32(op.check_type), |
| 32 | + attributes: Some(op.attributes.try_into()?), |
| 33 | + }) |
| 34 | + } |
| 35 | +} |
| 36 | + |
| 37 | +impl TryFrom<Result> for ResultProto { |
| 38 | + type Error = ResponseStatus; |
| 39 | + |
| 40 | + fn try_from(_result: Result) -> std::result::Result<Self, Self::Error> { |
| 41 | + Ok(ResultProto {}) |
| 42 | + } |
| 43 | +} |
| 44 | + |
| 45 | +impl TryFrom<ResultProto> for Result { |
| 46 | + type Error = ResponseStatus; |
| 47 | + |
| 48 | + fn try_from(_response: ResultProto) -> std::result::Result<Self, Self::Error> { |
| 49 | + Ok(Result {}) |
| 50 | + } |
| 51 | +} |
| 52 | + |
| 53 | +// CheckType: from protobuf to native |
| 54 | +impl TryFrom<CheckTypeProto> for CheckType { |
| 55 | + type Error = ResponseStatus; |
| 56 | + |
| 57 | + fn try_from(check_type_proto_val: CheckTypeProto) -> std::result::Result<Self, Self::Error> { |
| 58 | + match check_type_proto_val { |
| 59 | + CheckTypeProto::ChecktypeNone => Err(ResponseStatus::InvalidEncoding), |
| 60 | + CheckTypeProto::Use => Ok(CheckType::Use), |
| 61 | + CheckTypeProto::Generate => Ok(CheckType::Generate), |
| 62 | + CheckTypeProto::Import => Ok(CheckType::Import), |
| 63 | + CheckTypeProto::Derive => Ok(CheckType::Derive), |
| 64 | + } |
| 65 | + } |
| 66 | +} |
| 67 | + |
| 68 | +// CheckType: from native to protobuf |
| 69 | +impl TryFrom<CheckType> for CheckTypeProto { |
| 70 | + type Error = ResponseStatus; |
| 71 | + |
| 72 | + fn try_from(check_type_val: CheckType) -> std::result::Result<Self, Self::Error> { |
| 73 | + match check_type_val { |
| 74 | + CheckType::Use => Ok(CheckTypeProto::Use), |
| 75 | + CheckType::Generate => Ok(CheckTypeProto::Generate), |
| 76 | + CheckType::Import => Ok(CheckTypeProto::Import), |
| 77 | + CheckType::Derive => Ok(CheckTypeProto::Derive), |
| 78 | + } |
| 79 | + } |
| 80 | +} |
| 81 | + |
| 82 | +// CheckType from protobuf to native |
| 83 | +pub fn i32_to_check_type(check_type_val: i32) -> std::result::Result<CheckType, ResponseStatus> { |
| 84 | + let check_type_proto: CheckTypeProto = check_type_val.try_into()?; |
| 85 | + check_type_proto.try_into() |
| 86 | +} |
| 87 | + |
| 88 | +// CheckType from native to protobuf |
| 89 | +pub fn check_type_to_i32(check_type: CheckType) -> i32 { |
| 90 | + match check_type { |
| 91 | + CheckType::Use => CheckTypeProto::Use.into(), |
| 92 | + CheckType::Generate => CheckTypeProto::Generate.into(), |
| 93 | + CheckType::Import => CheckTypeProto::Import.into(), |
| 94 | + CheckType::Derive => CheckTypeProto::Derive.into(), |
| 95 | + } |
| 96 | +} |
| 97 | + |
| 98 | +#[cfg(test)] |
| 99 | +mod test { |
| 100 | + |
| 101 | + use super::super::generated_ops::can_do_crypto::Operation as OperationProto; |
| 102 | + use crate::operations::can_do_crypto::{CheckType, Operation}; |
| 103 | + use crate::operations::psa_algorithm::{Algorithm, AsymmetricSignature, Hash}; |
| 104 | + use crate::operations::psa_key_attributes::{self, Attributes, Lifetime, Policy, UsageFlags}; |
| 105 | + use crate::operations_protobuf::convert_can_do_crypto::check_type_to_i32; |
| 106 | + use std::convert::TryInto; |
| 107 | + |
| 108 | + #[test] |
| 109 | + fn proto_to_resp() { |
| 110 | + let mut usage_flags: UsageFlags = Default::default(); |
| 111 | + let _ = usage_flags |
| 112 | + .set_export() |
| 113 | + .set_copy() |
| 114 | + .set_cache() |
| 115 | + .set_encrypt() |
| 116 | + .set_decrypt() |
| 117 | + .set_sign_message() |
| 118 | + .set_verify_message() |
| 119 | + .set_sign_hash() |
| 120 | + .set_verify_hash() |
| 121 | + .set_derive(); |
| 122 | + let key_attrs = Attributes { |
| 123 | + lifetime: Lifetime::Persistent, |
| 124 | + key_type: psa_key_attributes::Type::RsaKeyPair, |
| 125 | + bits: 1024, |
| 126 | + policy: Policy { |
| 127 | + usage_flags, |
| 128 | + permitted_algorithms: Algorithm::AsymmetricSignature( |
| 129 | + AsymmetricSignature::RsaPkcs1v15Sign { |
| 130 | + hash_alg: Hash::Sha1.into(), |
| 131 | + }, |
| 132 | + ), |
| 133 | + }, |
| 134 | + }; |
| 135 | + let proto = OperationProto { |
| 136 | + check_type: check_type_to_i32(CheckType::Use), |
| 137 | + attributes: Some(key_attrs.try_into().expect("Failed conversion")), |
| 138 | + }; |
| 139 | + |
| 140 | + let resp: Operation = proto.try_into().expect("Failed conversion"); |
| 141 | + |
| 142 | + assert_eq!(resp.check_type, CheckType::Use); |
| 143 | + assert_eq!(resp.attributes, key_attrs); |
| 144 | + } |
| 145 | + |
| 146 | + #[test] |
| 147 | + fn resp_to_proto() { |
| 148 | + let mut usage_flags: UsageFlags = Default::default(); |
| 149 | + let _ = usage_flags |
| 150 | + .set_export() |
| 151 | + .set_copy() |
| 152 | + .set_cache() |
| 153 | + .set_encrypt() |
| 154 | + .set_decrypt() |
| 155 | + .set_sign_message() |
| 156 | + .set_verify_message() |
| 157 | + .set_sign_hash() |
| 158 | + .set_verify_hash() |
| 159 | + .set_derive(); |
| 160 | + let key_attrs = Attributes { |
| 161 | + lifetime: Lifetime::Persistent, |
| 162 | + key_type: psa_key_attributes::Type::RsaKeyPair, |
| 163 | + bits: 1024, |
| 164 | + policy: Policy { |
| 165 | + usage_flags, |
| 166 | + permitted_algorithms: Algorithm::AsymmetricSignature( |
| 167 | + AsymmetricSignature::RsaPkcs1v15Sign { |
| 168 | + hash_alg: Hash::Sha1.into(), |
| 169 | + }, |
| 170 | + ), |
| 171 | + }, |
| 172 | + }; |
| 173 | + let resp: Operation = Operation { |
| 174 | + check_type: CheckType::Use, |
| 175 | + attributes: key_attrs, |
| 176 | + }; |
| 177 | + |
| 178 | + let proto: OperationProto = resp.try_into().expect("Failed conversion"); |
| 179 | + |
| 180 | + assert_eq!(proto.check_type, check_type_to_i32(CheckType::Use)); |
| 181 | + assert_eq!( |
| 182 | + proto.attributes.expect("Failed conversion"), |
| 183 | + key_attrs.try_into().expect("Failed conversion") |
| 184 | + ); |
| 185 | + } |
| 186 | +} |
0 commit comments