use super::generated_ops::psa_import_key::{Operation as OperationProto, Result as ResultProto};
use crate::operations::psa_import_key::{Operation, Result};
use crate::requests::ResponseStatus;
use crate::secrecy::ExposeSecret;
use crate::secrecy::Secret;
use log::error;
use std::convert::{TryFrom, TryInto};
impl TryFrom<OperationProto> for Operation {
type Error = ResponseStatus;
fn try_from(proto_op: OperationProto) -> std::result::Result<Self, Self::Error> {
let data = Secret::new(proto_op.data);
Ok(Operation {
key_name: proto_op.key_name,
attributes: proto_op
.attributes
.ok_or_else(|| {
error!("The attributes field of PsaImportKey::Operation message is not set (mandatory field).");
ResponseStatus::InvalidEncoding
})?
.try_into()?,
data,
})
}
}
impl TryFrom<Operation> for OperationProto {
type Error = ResponseStatus;
fn try_from(op: Operation) -> std::result::Result<Self, Self::Error> {
Ok(OperationProto {
key_name: op.key_name,
attributes: Some(op.attributes.try_into()?),
data: op.data.expose_secret().to_vec(),
})
}
}
impl TryFrom<ResultProto> for Result {
type Error = ResponseStatus;
fn try_from(_proto_op: ResultProto) -> std::result::Result<Self, Self::Error> {
Ok(Result {})
}
}
impl TryFrom<Result> for ResultProto {
type Error = ResponseStatus;
fn try_from(_op: Result) -> std::result::Result<Self, Self::Error> {
Ok(ResultProto {})
}
}
#[cfg(test)]
mod test {
#![allow(deprecated)]
use super::super::generated_ops::psa_algorithm::{
self as algorithm_proto, Algorithm as AlgorithmProto,
};
use super::super::generated_ops::psa_import_key::{
Operation as OperationProto, Result as ResultProto,
};
use super::super::generated_ops::psa_key_attributes::{
self as key_attributes_proto, KeyAttributes as KeyAttributesProto,
};
use super::super::{Convert, ProtobufConverter};
use crate::operations::psa_algorithm::{Algorithm, AsymmetricSignature, Hash};
use crate::operations::psa_key_attributes::{self, Attributes, Lifetime, Policy, UsageFlags};
use crate::operations::{psa_import_key::Operation, psa_import_key::Result, NativeOperation};
use crate::requests::Opcode;
use crate::secrecy::{ExposeSecret, Secret};
use std::convert::TryInto;
static CONVERTER: ProtobufConverter = ProtobufConverter {};
#[test]
fn psa_import_key_op_from_proto() {
let name = "test name".to_string();
let key_data = vec![0x11, 0x22, 0x33];
let proto = OperationProto {
key_name: name.clone(),
attributes: Some(get_key_attrs_proto()),
data: key_data.clone(),
};
let op: Operation = proto.try_into().expect("Failed conversion");
assert_eq!(op.key_name, name);
assert_eq!(op.data.expose_secret(), &key_data);
}
#[test]
fn psa_import_key_op_to_proto() {
let name = "test name".to_string();
let key_data = vec![0x11, 0x22, 0x33];
let op = Operation {
key_name: name.clone(),
attributes: get_key_attrs(),
data: Secret::new(key_data.clone()),
};
let proto: OperationProto = op.try_into().expect("Failed conversion");
assert_eq!(proto.key_name, name);
assert_eq!(proto.data, key_data);
}
#[test]
fn psa_import_key_res_from_proto() {
let proto = ResultProto {};
let _res: Result = proto.try_into().expect("Failed conversion");
}
#[test]
fn psa_import_key_res_to_proto() {
let res = Result {};
let _proto: ResultProto = res.try_into().expect("Failed conversion");
}
#[test]
fn psa_import_key_op_e2e() {
let name = "test name".to_string();
let op = Operation {
key_name: name,
attributes: get_key_attrs(),
data: Secret::new(vec![0x11, 0x22, 0x33]),
};
let body = CONVERTER
.operation_to_body(NativeOperation::PsaImportKey(op))
.expect("Failed to convert to body");
let _ = CONVERTER
.body_to_operation(body, Opcode::PsaImportKey)
.expect("Failed to convert to operation");
}
fn get_key_attrs() -> Attributes {
let mut usage_flags = UsageFlags::default();
let _ = usage_flags
.set_decrypt()
.set_export()
.set_copy()
.set_cache()
.set_encrypt()
.set_decrypt()
.set_sign_message()
.set_verify_message()
.set_sign_hash()
.set_verify_hash()
.set_derive();
Attributes {
lifetime: Lifetime::Persistent,
key_type: psa_key_attributes::Type::RsaKeyPair,
bits: 1024,
policy: Policy {
usage_flags,
permitted_algorithms: Algorithm::AsymmetricSignature(
AsymmetricSignature::RsaPkcs1v15Sign {
hash_alg: Hash::Sha1.into(),
},
),
},
}
}
fn get_key_attrs_proto() -> KeyAttributesProto {
KeyAttributesProto {
key_type: Some(key_attributes_proto::KeyType {
variant: Some(key_attributes_proto::key_type::Variant::RsaKeyPair(key_attributes_proto::key_type::RsaKeyPair {})),
}),
key_bits: 1024,
key_policy: Some(key_attributes_proto::KeyPolicy {
key_usage_flags: Some(key_attributes_proto::UsageFlags {
export: true,
copy: true,
cache: true,
encrypt: true,
decrypt: true,
sign_message: true,
verify_message: true,
sign_hash: true,
verify_hash: true,
derive: true,
}),
key_algorithm: Some(AlgorithmProto {
variant: Some(algorithm_proto::algorithm::Variant::AsymmetricSignature(algorithm_proto::algorithm::AsymmetricSignature {
variant: Some(algorithm_proto::algorithm::asymmetric_signature::Variant::RsaPkcs1v15Sign(algorithm_proto::algorithm::asymmetric_signature::RsaPkcs1v15Sign {
hash_alg: Some(algorithm_proto::algorithm::asymmetric_signature::SignHash {
variant: Some(algorithm_proto::algorithm::asymmetric_signature::sign_hash::Variant::Specific(
algorithm_proto::algorithm::Hash::Sha1.into(),
)),
}),
})),
}))
}),
}),
}
}
}