#![allow(clippy::multiple_crate_versions)]
use psa_crypto::operations::key_management;
use psa_crypto::types::algorithm::{Algorithm, AsymmetricSignature, Hash};
use psa_crypto::types::key::{Attributes, EccFamily, Lifetime, Policy, Type, UsageFlags};
mod aead;
mod hash;
mod key_agreement;
#[test]
fn generate_integration_test() {
let mut usage_flags: UsageFlags = Default::default();
usage_flags.set_verify_message();
let attributes = Attributes {
lifetime: Lifetime::Persistent,
key_type: Type::RsaKeyPair,
bits: 1024,
policy: Policy {
usage_flags,
permitted_algorithms: Algorithm::AsymmetricSignature(
AsymmetricSignature::RsaPkcs1v15Sign {
hash_alg: Hash::Sha256.into(),
},
),
},
};
let mut test_client = test_tools::TestClient::new();
for key_index in 1..101u32 {
test_client.generate(attributes, Some(key_index));
}
}
#[test]
fn import_integration_test() {
const KEY_DATA: [u8; 140] = [
48, 129, 137, 2, 129, 129, 0, 153, 165, 220, 135, 89, 101, 254, 229, 28, 33, 138, 247, 20,
102, 253, 217, 247, 246, 142, 107, 51, 40, 179, 149, 45, 117, 254, 236, 161, 109, 16, 81,
135, 72, 112, 132, 150, 175, 128, 173, 182, 122, 227, 214, 196, 130, 54, 239, 93, 5, 203,
185, 233, 61, 159, 156, 7, 161, 87, 48, 234, 105, 161, 108, 215, 211, 150, 168, 156, 212,
6, 63, 81, 24, 101, 72, 160, 97, 243, 142, 86, 10, 160, 122, 8, 228, 178, 252, 35, 209,
222, 228, 16, 143, 99, 143, 146, 241, 186, 187, 22, 209, 86, 141, 24, 159, 12, 146, 44,
111, 254, 183, 54, 229, 109, 28, 39, 22, 141, 173, 85, 26, 58, 9, 128, 27, 57, 131, 2, 3,
1, 0, 1,
];
let mut usage_flags: UsageFlags = Default::default();
usage_flags.set_verify_hash().set_sign_hash();
let attributes = Attributes {
lifetime: Lifetime::Persistent,
key_type: Type::RsaPublicKey,
bits: 1024,
policy: Policy {
usage_flags,
permitted_algorithms: AsymmetricSignature::RsaPkcs1v15Sign {
hash_alg: Hash::Sha256.into(),
}
.into(),
},
};
let mut test_client = test_tools::TestClient::new();
for key_index in 101..201u32 {
test_client.import(attributes, key_index, &KEY_DATA);
}
}
#[test]
fn export_key_pair_test() {
const PRIVATE_KEY: &str = "MIICWwIBAAKBgQCd+EKeRmZCKLmg7LasWqpKA9/01linY75ujilf6v/Kb8UP9r/E\
cO75Pvi2YPnYhBadmVOVxMOqS2zmKm1a9VTegT8dN9Unf2s2KbKrKXupaQTXcrGG\
SB/BmHeWeiqidEMw7i9ysjHK4KEuacmYmZpvKAnNWMyvQgjGgGNpsNzqawIDAQAB\
AoGAcHlAxXyOdnCUqpWgAtuS/5v+q06qVJRaFFE3+ElT0oj+ID2pkG5wWBqT7xbh\
DV4O1CtFLg+o2OlXIhH3RpoC0D0x3qfvDpY5nJUUhP/w7mtGOwvB08xhXBN2M9fk\
PNqGdrzisvxTry3rp9qDduZlv1rTCsx8+ww3iI4Q0coD4fECQQD4KAMgIS7Vu+Vm\
zQmJfVfzYCVdr4X3Z/JOEexb3eu9p1Qj904sLu9Ds5NO7atT+qtDYVxgH5kQIrKk\
mFNAx3NdAkEAovZ+DaorhkDiL/gFVzwoShyc1A6AWkH791sDlns2ETZ1WwE/ccYu\
uJill/5XA9RKw6whUDzzNTsv7bFkCruAZwJARP5y6ALxz5DfFfbZuPU1d7/6g5Ki\
b4fh8VzAV0ZbHa6hESLYBCbEdRE/WolvwfiGl0RBd6QxXTAYdPS46ODLLQJARrz4\
urXDbuN7S5c9ukBCvOjuqp4g2Q0LcrPvOsMBFTeueXJxN9HvNfIM741X+DGOwqFV\
VJ8gc1rd0y/NXVtGwQJAc2w23nTmZ/olcMVRia1+AFsELcCnD+JqaJ2AEF1Ng6Ix\
V/X2l32v6t3B57sw/8ce3LCheEdqLHlSOpQiaD7Qfw==";
let mut usage_flags: UsageFlags = Default::default();
usage_flags.set_sign_hash().set_verify_hash().set_export();
let attributes = Attributes {
key_type: Type::RsaKeyPair,
bits: 1024,
lifetime: Lifetime::Volatile,
policy: Policy {
usage_flags,
permitted_algorithms: AsymmetricSignature::RsaPkcs1v15Sign {
hash_alg: Hash::Sha256.into(),
}
.into(),
},
};
psa_crypto::init().unwrap();
let mut test_client = test_tools::TestClient::new();
let decoded_pk = base64::decode(PRIVATE_KEY).unwrap();
let id = test_client.import(attributes, 201, &decoded_pk);
let buffer_size = attributes.export_key_output_size().unwrap();
let mut data = vec![0; buffer_size];
let size = test_client.export_key_pair(id, &mut data).unwrap();
data.resize(size, 0);
assert_eq!(decoded_pk, data);
}
#[test]
fn copy_key_success() {
let mut usage_flags: UsageFlags = Default::default();
usage_flags.set_export().set_copy();
let attributes = Attributes {
key_type: Type::RsaKeyPair,
bits: 1024,
lifetime: Lifetime::Volatile,
policy: Policy {
usage_flags,
permitted_algorithms: Algorithm::None,
},
};
let mut test_client = test_tools::TestClient::new();
let key_id = test_client.generate(attributes, None);
let copied_key_id = test_client.copy_key(key_id, attributes, None);
let mut original_key_material = vec![0; attributes.export_key_output_size().unwrap()];
let mut copied_key_material = vec![0; attributes.export_key_output_size().unwrap()];
test_client
.export_key_pair(key_id, &mut original_key_material)
.unwrap();
test_client
.export_key_pair(copied_key_id, &mut copied_key_material)
.unwrap();
assert_eq!(original_key_material, copied_key_material);
}
#[test]
fn copy_key_incompatible_copy_attrs() {
let mut usage_flags: UsageFlags = Default::default();
usage_flags.set_copy().set_export();
let attributes = Attributes {
key_type: Type::RsaKeyPair,
bits: 1024,
lifetime: Lifetime::Volatile,
policy: Policy {
usage_flags,
permitted_algorithms: Algorithm::None,
},
};
let mut usage_flags: UsageFlags = Default::default();
usage_flags.set_copy().set_export();
let incompatible_copy_attrs = Attributes {
key_type: Type::EccKeyPair {
curve_family: EccFamily::SecpR1,
},
bits: 448,
lifetime: Lifetime::Volatile,
policy: Policy {
usage_flags,
permitted_algorithms: Algorithm::None,
},
};
let mut test_client = test_tools::TestClient::new();
let key_id = test_client.generate(attributes, None);
let _copied_key_id = key_management::copy(key_id, incompatible_copy_attrs, None).unwrap_err();
}
mod test_tools {
use psa_crypto::operations::key_management;
use psa_crypto::types::key::{Attributes, Id};
use psa_crypto::types::status::Result;
pub struct TestClient {
keys: Vec<Id>,
}
impl TestClient {
pub fn new() -> Self {
psa_crypto::init().unwrap();
TestClient { keys: Vec::new() }
}
pub fn generate(&mut self, attributes: Attributes, key_id: Option<u32>) -> Id {
let id = key_management::generate(attributes, key_id).unwrap();
self.keys.push(id);
id
}
pub fn import(&mut self, attributes: Attributes, key_id: u32, key_data: &[u8]) -> Id {
let id = key_management::import(attributes, Some(key_id), key_data).unwrap();
self.keys.push(id);
id
}
pub fn export_key_pair(&mut self, key_id: Id, key_data: &mut [u8]) -> Result<usize> {
key_management::export(key_id, key_data)
}
pub fn copy_key(
&mut self,
key_id: Id,
attributes: Attributes,
id_for_new_persistent_key: Option<u32>,
) -> Id {
let id = key_management::copy(key_id, attributes, id_for_new_persistent_key).unwrap();
self.keys.push(id);
id
}
}
impl Drop for TestClient {
fn drop(&mut self) {
for key in self.keys.clone() {
unsafe { key_management::destroy(key) }.unwrap();
}
}
}
}