// Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 #![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(); // Ensure that a large number of keys can be generated 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(); // Ensure that a large number of keys can be imported 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, } impl TestClient { pub fn new() -> Self { psa_crypto::init().unwrap(); TestClient { keys: Vec::new() } } pub fn generate(&mut self, attributes: Attributes, key_id: Option) -> 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 { key_management::export(key_id, key_data) } pub fn copy_key( &mut self, key_id: Id, attributes: Attributes, id_for_new_persistent_key: Option, ) -> 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(); } } } }