diff --git a/Cargo.toml b/Cargo.toml index 7485d444..60bdb26c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ name = "parsec" path = "src/bin/main.rs" [dependencies] -parsec-interface = { git = "https://github.com/parallaxsecond/parsec-interface-rs.git", rev = "6b951390791b398b76eb02c942e24d7c91acc980"} +parsec-interface = { git = "https://github.com/Kakemone/parsec-interface-rs", branch = "CanDoCrypto_patch" } rand = { version = "0.8.3", features = ["small_rng"], optional = true } base64 = "0.13.0" uuid = "0.8.2" @@ -26,7 +26,7 @@ toml = "0.5.8" serde = { version = "1.0.123", features = ["derive"] } env_logger = "0.8.3" log = { version = "0.4.14", features = ["serde"] } -cryptoki = { git = "https://github.com/parallaxsecond/rust-cryptoki", rev = "916f9bbb208ba8a671c593a36313f09c60cd0255", optional = true, features = ["psa-crypto-conversions"] } +cryptoki = { version = "0.2.0", optional = true, features = ["psa-crypto-conversions"] } picky-asn1-der = { version = "<=0.2.4", optional = true } picky-asn1 = { version = ">=0.3.1, <=0.3.1", optional = true } tss-esapi = { git = "https://github.com/parallaxsecond/rust-tss-esapi", rev = "1f68655e278b0319c080b9804a7bf3f6e11ff721", optional = true } @@ -35,7 +35,7 @@ structopt = "0.3.21" derivative = "2.2.0" version = "3.0.0" hex = { version = "0.4.2", optional = true } -psa-crypto = { git = "https://github.com/parallaxsecond/rust-psa-crypto.git", rev = "8605006d34944fa880edd3d4d347f460c5585747", default-features = false, features = ["operations"], optional = true } +psa-crypto = { version = "0.9.0", default-features = false, features = ["operations"], optional = true } zeroize = { version = "1.2.0", features = ["zeroize_derive"] } picky-asn1-x509 = { version = "0.4.0", optional = true } users = "0.11.0" diff --git a/e2e_tests/Cargo.toml b/e2e_tests/Cargo.toml index c373bac9..68f886c6 100644 --- a/e2e_tests/Cargo.toml +++ b/e2e_tests/Cargo.toml @@ -11,7 +11,7 @@ publish = false [dependencies] serde = { version = "1.0.123", features = ["derive"] } -parsec-client = { git = "https://github.com/parallaxsecond/parsec-client-rust.git", rev = "e7c8989aed83343d2d86896f811fbe49f7d0edfc", features = ["testing", "spiffe-auth"] } +parsec-client = { git = "https://github.com/Kakemone/parsec-client-rust", branch = "CanDoCrypto_patch", features = ["testing", "spiffe-auth"] } log = "0.4.14" # Compatible version with crate rsa rand = "0.7.3" diff --git a/e2e_tests/src/lib.rs b/e2e_tests/src/lib.rs index 5171acae..104e5348 100644 --- a/e2e_tests/src/lib.rs +++ b/e2e_tests/src/lib.rs @@ -12,6 +12,7 @@ pub use parsec_client::error; use log::error; use parsec_client::auth::Authentication; use parsec_client::core::basic_client::BasicClient; +use parsec_client::core::interface::operations::can_do_crypto::CheckType; use parsec_client::core::interface::operations::list_authenticators::AuthenticatorInfo; use parsec_client::core::interface::operations::list_keys::KeyInfo; use parsec_client::core::interface::operations::list_providers::ProviderInfo; @@ -124,6 +125,12 @@ impl TestClient { /// Generate a 1024 bits RSA key pair. /// The key can only be used for signing/verifying with the RSA PKCS 1v15 signing algorithm with SHA-256 and exporting its public part. pub fn generate_rsa_sign_key(&mut self, key_name: String) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags + .set_sign_hash() + .set_verify_hash() + .set_sign_message() + .set_verify_message(); self.generate_key( key_name, Attributes { @@ -131,18 +138,7 @@ impl TestClient { key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: true, - verify_hash: true, - sign_message: true, - verify_message: true, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), @@ -154,6 +150,12 @@ impl TestClient { } pub fn generate_long_rsa_sign_key(&mut self, key_name: String) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags + .set_sign_hash() + .set_verify_hash() + .set_sign_message() + .set_verify_message(); self.generate_key( key_name, Attributes { @@ -161,18 +163,7 @@ impl TestClient { key_type: Type::RsaKeyPair, bits: 2048, policy: Policy { - usage_flags: UsageFlags { - sign_hash: true, - verify_hash: true, - sign_message: true, - verify_message: true, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), @@ -187,6 +178,8 @@ impl TestClient { &mut self, key_name: String, ) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_encrypt().set_decrypt(); self.generate_key( key_name, Attributes { @@ -194,18 +187,7 @@ impl TestClient { key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: true, - decrypt: true, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: AsymmetricEncryption::RsaPkcs1v15Crypt.into(), }, }, @@ -213,6 +195,8 @@ impl TestClient { } pub fn generate_aes_keys_ccm(&mut self, key_name: String) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_encrypt().set_decrypt(); self.generate_key( key_name, Attributes { @@ -220,18 +204,7 @@ impl TestClient { key_type: Type::Aes, bits: 192, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: true, - decrypt: true, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Aead::AeadWithDefaultLengthTag( AeadWithDefaultLengthTag::Ccm, ) @@ -242,6 +215,8 @@ impl TestClient { } pub fn generate_rsa_encryption_keys_rsaoaep_sha256(&mut self, key_name: String) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_encrypt().set_decrypt(); self.generate_key( key_name, Attributes { @@ -249,18 +224,7 @@ impl TestClient { key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: true, - decrypt: true, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: AsymmetricEncryption::RsaOaep { hash_alg: Hash::Sha256, } @@ -272,6 +236,8 @@ impl TestClient { #[allow(deprecated)] pub fn generate_rsa_encryption_keys_rsaoaep_sha1(&mut self, key_name: String) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_encrypt().set_decrypt(); self.generate_key( key_name, Attributes { @@ -279,18 +245,7 @@ impl TestClient { key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: true, - decrypt: true, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: AsymmetricEncryption::RsaOaep { hash_alg: Hash::Sha1, } @@ -304,6 +259,11 @@ impl TestClient { &mut self, key_name: String, ) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags + .set_sign_hash() + .set_verify_hash() + .set_sign_message(); self.generate_key( key_name, Attributes { @@ -313,18 +273,7 @@ impl TestClient { }, bits: 256, policy: Policy { - usage_flags: UsageFlags { - sign_hash: true, - verify_hash: true, - sign_message: true, - verify_message: false, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: AsymmetricSignature::DeterministicEcdsa { hash_alg: Hash::Sha256.into(), } @@ -335,6 +284,12 @@ impl TestClient { } pub fn generate_ecc_key_pair_secpr1_ecdsa_sha256(&mut self, key_name: String) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags + .set_sign_hash() + .set_verify_hash() + .set_sign_message() + .set_verify_message(); self.generate_key( key_name, Attributes { @@ -344,18 +299,7 @@ impl TestClient { }, bits: 256, policy: Policy { - usage_flags: UsageFlags { - sign_hash: true, - verify_hash: true, - sign_message: true, - verify_message: true, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: AsymmetricSignature::Ecdsa { hash_alg: Hash::Sha256.into(), } @@ -368,6 +312,8 @@ impl TestClient { /// Generate ECC key pair with secp R1 curve family. /// The key can only be used for key agreement with Ecdh algorithm. pub fn generate_ecc_pair_secp_r1_key(&mut self, key_name: String) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_derive(); let attributes = Attributes { key_type: Type::EccKeyPair { curve_family: EccFamily::SecpR1, @@ -375,10 +321,7 @@ impl TestClient { bits: 256, lifetime: Lifetime::Volatile, policy: Policy { - usage_flags: UsageFlags { - derive: true, - ..Default::default() - }, + usage_flags, permitted_algorithms: KeyAgreement::Raw(RawKeyAgreement::Ecdh).into(), }, }; @@ -413,6 +356,8 @@ impl TestClient { key_name: String, data: Vec, ) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_encrypt().set_decrypt(); self.import_key( key_name, Attributes { @@ -420,18 +365,7 @@ impl TestClient { key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: true, - decrypt: true, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: AsymmetricEncryption::RsaPkcs1v15Crypt.into(), }, }, @@ -444,6 +378,8 @@ impl TestClient { key_name: String, data: Vec, ) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_encrypt().set_decrypt().set_verify_message(); self.import_key( key_name, Attributes { @@ -451,18 +387,7 @@ impl TestClient { key_type: Type::RsaPublicKey, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: true, - export: false, - encrypt: true, - decrypt: true, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: AsymmetricEncryption::RsaPkcs1v15Crypt.into(), }, }, @@ -473,6 +398,8 @@ impl TestClient { /// Import a 1024 bit RSA public key. /// The key can only be used for verifying with the RSA PKCS 1v15 signing algorithm with SHA-256. pub fn import_rsa_public_key(&mut self, key_name: String, data: Vec) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_verify_hash().set_verify_message(); self.import_key( key_name, Attributes { @@ -480,18 +407,7 @@ impl TestClient { key_type: Type::RsaPublicKey, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: true, - sign_message: false, - verify_message: true, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), @@ -506,6 +422,8 @@ impl TestClient { /// Import an AES key. /// The key can only be used for AEAD encryption and decryption with the CCM algorithm pub fn import_aes_key(&mut self, key_name: String, data: Vec) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_encrypt().set_decrypt(); self.import_key( key_name, Attributes { @@ -513,18 +431,7 @@ impl TestClient { key_type: Type::Aes, bits: 0, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: true, - decrypt: true, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Aead::AeadWithDefaultLengthTag( AeadWithDefaultLengthTag::Ccm, ) @@ -538,6 +445,8 @@ impl TestClient { /// Import ECC key pair with secp R1 curve family. /// The key can only be used for key agreement with Ecdh algorithm. pub fn import_ecc_pair_secp_r1_key(&mut self, key_name: String, data: Vec) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_derive(); let attributes = Attributes { key_type: Type::EccKeyPair { curve_family: EccFamily::SecpR1, @@ -545,10 +454,7 @@ impl TestClient { bits: 256, lifetime: Lifetime::Volatile, policy: Policy { - usage_flags: UsageFlags { - derive: true, - ..Default::default() - }, + usage_flags, permitted_algorithms: KeyAgreement::Raw(RawKeyAgreement::Ecdh).into(), }, }; @@ -562,6 +468,8 @@ impl TestClient { key_name: String, data: Vec, ) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_derive(); let attributes = Attributes { key_type: Type::EccKeyPair { curve_family: EccFamily::BrainpoolPR1, @@ -569,10 +477,7 @@ impl TestClient { bits: 0, lifetime: Lifetime::Volatile, policy: Policy { - usage_flags: UsageFlags { - derive: true, - ..Default::default() - }, + usage_flags, permitted_algorithms: KeyAgreement::Raw(RawKeyAgreement::Ecdh).into(), }, }; @@ -586,6 +491,8 @@ impl TestClient { key_name: String, data: Vec, ) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_verify_hash().set_verify_message(); self.import_key( key_name, Attributes { @@ -595,18 +502,7 @@ impl TestClient { }, bits: 256, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: true, - sign_message: false, - verify_message: true, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: AsymmetricSignature::Ecdsa { hash_alg: Hash::Sha256.into(), } @@ -622,6 +518,12 @@ impl TestClient { key_name: String, data: Vec, ) -> Result<()> { + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags + .set_sign_hash() + .set_sign_message() + .set_verify_hash() + .set_verify_message(); self.import_key( key_name, Attributes { @@ -631,18 +533,7 @@ impl TestClient { }, bits: 256, policy: Policy { - usage_flags: UsageFlags { - sign_hash: true, - verify_hash: true, - sign_message: true, - verify_message: true, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: AsymmetricSignature::Ecdsa { hash_alg: Hash::Sha256.into(), } @@ -1026,6 +917,13 @@ impl TestClient { pub fn ping(&mut self) -> Result<(u8, u8)> { self.basic_client.ping().map_err(convert_error) } + + ///Executes the CanDoCrypto operation. + pub fn can_do_crypto(&self, check_type: CheckType, attributes: Attributes) -> Result<()> { + self.basic_client + .can_do_crypto(check_type, attributes) + .map_err(convert_error) + } } impl Default for TestClient { diff --git a/e2e_tests/tests/per_provider/normal_tests/asym_encryption.rs b/e2e_tests/tests/per_provider/normal_tests/asym_encryption.rs index d25851b3..f5803ad4 100644 --- a/e2e_tests/tests/per_provider/normal_tests/asym_encryption.rs +++ b/e2e_tests/tests/per_provider/normal_tests/asym_encryption.rs @@ -371,23 +371,14 @@ fn asym_encrypt_not_permitted() { return; } + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_decrypt(); let attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: false, - decrypt: true, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: AsymmetricEncryption::RsaPkcs1v15Crypt.into(), }, }; @@ -409,23 +400,14 @@ fn asym_decrypt_not_permitted() { return; } + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_encrypt(); let attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: true, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: AsymmetricEncryption::RsaPkcs1v15Crypt.into(), }, }; diff --git a/e2e_tests/tests/per_provider/normal_tests/asym_sign_verify.rs b/e2e_tests/tests/per_provider/normal_tests/asym_sign_verify.rs index e4ae1bc8..bccd55cd 100644 --- a/e2e_tests/tests/per_provider/normal_tests/asym_sign_verify.rs +++ b/e2e_tests/tests/per_provider/normal_tests/asym_sign_verify.rs @@ -236,23 +236,14 @@ fn sign_hash_not_permitted() -> Result<()> { hasher.update(b"Bob wrote this message."); let hash = hasher.finalize().to_vec(); + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_message().set_verify_hash().set_verify_message(); let attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: true, - sign_message: true, - verify_message: true, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), @@ -286,6 +277,8 @@ fn sign_hash_not_permitted_ecc() -> Result<()> { hasher.update(b"Bob wrote this message."); let hash = hasher.finalize().to_vec(); + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_message().set_verify_hash().set_verify_message(); let attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::EccKeyPair { @@ -293,18 +286,7 @@ fn sign_hash_not_permitted_ecc() -> Result<()> { }, bits: 256, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: true, - sign_message: true, - verify_message: true, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { hash_alg: Hash::Sha256.into(), }), @@ -438,23 +420,14 @@ fn verify_hash_not_permitted_rsa() -> Result<()> { hasher.update(b"Bob wrote this message."); let hash = hasher.finalize().to_vec(); + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_message().set_sign_hash().set_verify_message(); let attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: true, - verify_hash: false, - sign_message: true, - verify_message: true, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), @@ -491,6 +464,8 @@ fn verify_hash_not_permitted_ecc() -> Result<()> { hasher.update(b"Bob wrote this message."); let hash = hasher.finalize().to_vec(); + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_message().set_sign_hash().set_verify_message(); let attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::EccKeyPair { @@ -498,18 +473,7 @@ fn verify_hash_not_permitted_ecc() -> Result<()> { }, bits: 256, policy: Policy { - usage_flags: UsageFlags { - sign_hash: true, - verify_hash: false, - sign_message: true, - verify_message: true, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { hash_alg: Hash::Sha256.into(), }), @@ -859,6 +823,7 @@ fn sign_message_not_permitted() { let msg = b"Bob wrote this message."; + let usage_flags: UsageFlags = Default::default(); client .generate_key( key_name.clone(), @@ -869,18 +834,7 @@ fn sign_message_not_permitted() { }, bits: 256, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: AsymmetricSignature::Ecdsa { hash_alg: Hash::Sha256.into(), } @@ -910,6 +864,8 @@ fn verify_message_not_permitted() { let msg = b"Bob wrote this message."; + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_message(); client .generate_key( key_name.clone(), @@ -920,18 +876,7 @@ fn verify_message_not_permitted() { }, bits: 256, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: true, - verify_message: false, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: AsymmetricSignature::Ecdsa { hash_alg: Hash::Sha256.into(), } @@ -957,6 +902,8 @@ fn verify_message_not_permitted() { fn wildcard_hash_not_supported() { let key_name = String::from("sign_verify_ecc"); let mut client = TestClient::new(); + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_hash().set_verify_hash(); assert_eq!( client @@ -967,18 +914,7 @@ fn wildcard_hash_not_supported() { key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: true, - verify_hash: true, - sign_message: false, - verify_message: false, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: SignHash::Any, diff --git a/e2e_tests/tests/per_provider/normal_tests/capability_discovery.rs b/e2e_tests/tests/per_provider/normal_tests/capability_discovery.rs new file mode 100644 index 00000000..31f4b3e7 --- /dev/null +++ b/e2e_tests/tests/per_provider/normal_tests/capability_discovery.rs @@ -0,0 +1,371 @@ +// Copyright 2021 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 +use e2e_tests::TestClient; +use parsec_client::core::interface::operations::psa_algorithm::*; +use parsec_client::core::interface::requests::{Opcode, ResponseStatus}; +use parsec_client::core::interface::operations::psa_key_attributes::*; +use parsec_client::core::interface::operations::can_do_crypto::CheckType; + +#[test] +fn derive_check() { + let mut client = TestClient::new(); + if !client.is_operation_supported(Opcode::CanDoCrypto) { + return + } + + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_derive(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaPublicKey, + bits: 1024, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::None, + }, + }; + + let status = client.can_do_crypto(CheckType::Derive, attributes); + + assert_eq!(Err(ResponseStatus::PsaErrorNotSupported), status) +} + +#[test] +fn key_size_check() { + let mut client = TestClient::new(); + if !client.is_operation_supported(Opcode::CanDoCrypto) { + return + } + + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_hash(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaPublicKey, + bits: 8, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }), + }, + }; + + let status = client.can_do_crypto(CheckType::Use, attributes); + + assert_eq!(Err(ResponseStatus::PsaErrorNotSupported), status); + + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_hash(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaPublicKey, + bits: 256, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }), + }, + }; + + let status = client.can_do_crypto(CheckType::Use, attributes); + + assert_eq!(Ok(()), status); + + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_hash(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaPublicKey, + bits: 1024, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }), + }, + }; + + let status = client.can_do_crypto(CheckType::Use, attributes); + + assert_eq!(Err(ResponseStatus::PsaErrorNotSupported), status) +} + +#[test] +fn use_check() { + let mut client = TestClient::new(); + if !client.is_operation_supported(Opcode::CanDoCrypto) { + return + } + + let usage_flags: UsageFlags = Default::default(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaPublicKey, + bits: 256, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::None, + }, + }; + + let status = client.can_do_crypto(CheckType::Use, attributes); + + assert_eq!(Err(ResponseStatus::PsaErrorNotSupported), status); + + let usage_flags: UsageFlags = Default::default(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaPublicKey, + bits: 256, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }), + }, + }; + + let status = client.can_do_crypto(CheckType::Use, attributes); + + assert_eq!(Err(ResponseStatus::PsaErrorNotSupported), status); + + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_hash(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaPublicKey, + bits: 256, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }), + }, + }; + + let status = client.can_do_crypto(CheckType::Use, attributes); + + assert_eq!(Ok(()), status); + + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_message(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaPublicKey, + bits: 256, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }), + }, + }; + + let status = client.can_do_crypto(CheckType::Use, attributes); + + assert_eq!(Ok(()), status); + + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_verify_hash(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaPublicKey, + bits: 256, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }), + }, + }; + + let status = client.can_do_crypto(CheckType::Use, attributes); + + assert_eq!(Ok(()), status); + + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_verify_message(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaPublicKey, + bits: 256, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }), + }, + }; + + let status = client.can_do_crypto(CheckType::Use, attributes); + + assert_eq!(Ok(()), status); + + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_decrypt(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaPublicKey, + bits: 256, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }), + }, + }; + + let status = client.can_do_crypto(CheckType::Use, attributes); + + assert_eq!(Ok(()), status); + + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_encrypt(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaPublicKey, + bits: 256, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }), + }, + }; + + let status = client.can_do_crypto(CheckType::Use, attributes); + + assert_eq!(Ok(()), status) +} + +#[test] +fn generate_check() { + let mut client = TestClient::new(); + if !client.is_operation_supported(Opcode::CanDoCrypto) { + return + } + + let usage_flags: UsageFlags = Default::default(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaKeyPair, + bits: 256, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature( + AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }, + ), + }, + }; + + let status = client.can_do_crypto(CheckType::Generate, attributes); + + assert_eq!(Ok(()), status); + + let usage_flags: UsageFlags = Default::default(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::EccKeyPair {curve_family: EccFamily::SecpR1}, + bits: 256, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature( + AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }, + ), + }, + }; + + let status = client.can_do_crypto(CheckType::Generate, attributes); + + assert_eq!(Ok(()), status); + + let usage_flags: UsageFlags = Default::default(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaPublicKey, + bits: 256, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature( + AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }, + ), + }, + }; + + let status = client.can_do_crypto(CheckType::Generate, attributes); + + assert_eq!(Err(ResponseStatus::PsaErrorNotSupported), status) +} + +#[test] +fn import_check() { + let mut client = TestClient::new(); + if !client.is_operation_supported(Opcode::CanDoCrypto) { + return + } + + let usage_flags: UsageFlags = Default::default(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaPublicKey, + bits: 256, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature( + AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }, + ), + }, + }; + + let status = client.can_do_crypto(CheckType::Import, attributes); + + assert_eq!(Ok(()), status); + + let usage_flags: UsageFlags = Default::default(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::EccPublicKey {curve_family: EccFamily::SecpR1}, + bits: 256, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature( + AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }, + ), + }, + }; + + let status = client.can_do_crypto(CheckType::Import, attributes); + + assert_eq!(Ok(()), status); + + let usage_flags: UsageFlags = Default::default(); + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaKeyPair, + bits: 256, + policy: Policy { + usage_flags, + permitted_algorithms: Algorithm::AsymmetricSignature( + AsymmetricSignature::Ecdsa { + hash_alg: Hash::Sha256.into(), + }, + ), + }, + }; + + let status = client.can_do_crypto(CheckType::Import, attributes); + + assert_eq!(Err(ResponseStatus::PsaErrorNotSupported), status) +} \ No newline at end of file diff --git a/e2e_tests/tests/per_provider/normal_tests/create_destroy_key.rs b/e2e_tests/tests/per_provider/normal_tests/create_destroy_key.rs index 8114801c..1ae17d5c 100644 --- a/e2e_tests/tests/per_provider/normal_tests/create_destroy_key.rs +++ b/e2e_tests/tests/per_provider/normal_tests/create_destroy_key.rs @@ -198,6 +198,8 @@ fn try_generate_asymmetric_public_key() { let mut client = TestClient::new(); let key_name = String::from("try_generate_asymmetric_public_key"); + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_hash().set_sign_message().set_verify_hash().set_verify_message(); let err = client .generate_key( key_name, @@ -206,18 +208,7 @@ fn try_generate_asymmetric_public_key() { key_type: Type::RsaPublicKey, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: true, - verify_hash: true, - sign_message: true, - verify_message: true, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), diff --git a/e2e_tests/tests/per_provider/normal_tests/export_key.rs b/e2e_tests/tests/per_provider/normal_tests/export_key.rs index c56cec9e..d2790ff9 100644 --- a/e2e_tests/tests/per_provider/normal_tests/export_key.rs +++ b/e2e_tests/tests/per_provider/normal_tests/export_key.rs @@ -44,24 +44,15 @@ fn export_key() -> Result<()> { return Ok(()); } + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_export(); let key_name = String::from("export_key"); let key_attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: true, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), @@ -129,6 +120,8 @@ fn import_and_export_ecc_public_key_by_export_key_fn() -> Result<()> { } let key_name = String::from("import_and_export_ecc_public_key_by_export_key_fn"); + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_export().set_verify_message().set_verify_hash(); client.import_key( key_name.clone(), Attributes { @@ -138,18 +131,7 @@ fn import_and_export_ecc_public_key_by_export_key_fn() -> Result<()> { }, bits: 256, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: true, - sign_message: false, - verify_message: true, - export: true, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: AsymmetricSignature::Ecdsa { hash_alg: Hash::Sha256.into(), } @@ -174,23 +156,14 @@ fn check_rsa_export_format() -> Result<()> { } let key_name = String::from("check_public_rsa_export_format"); + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_export(); let key_attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: true, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), @@ -218,24 +191,15 @@ fn check_export_rsa_possible() -> Result<()> { } let key_name = String::from("check_export_rsa_possible"); + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_export(); let key_attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: true, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), @@ -261,24 +225,14 @@ fn check_export_rsa_not_possible() { } let key_name = String::from("check_export_rsa_not_possible"); + let usage_flags: UsageFlags = Default::default(); let key_attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), @@ -305,6 +259,7 @@ fn check_export_ecc_not_possible() { } let key_name = String::from("check_export_ecc_not_possible"); + let usage_flags: UsageFlags = Default::default(); let key_attributes = Attributes { lifetime: Lifetime::Persistent, @@ -313,18 +268,7 @@ fn check_export_ecc_not_possible() { }, bits: 256, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { hash_alg: Hash::Sha256.into(), }), @@ -349,6 +293,8 @@ fn export_ecc_private_key() { } let key_name = String::from("export_ecc_private_key"); + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_export(); let key_attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::EccKeyPair { @@ -356,18 +302,7 @@ fn export_ecc_private_key() { }, bits: 256, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: true, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { hash_alg: Hash::Sha256.into(), }), @@ -391,6 +326,8 @@ fn export_ecc_private_key_not_possible() { } let key_name = String::from("export_ecc_private_key_not_possible"); + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_export(); let key_attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::EccKeyPair { @@ -398,18 +335,7 @@ fn export_ecc_private_key_not_possible() { }, bits: 256, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: true, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { hash_alg: Hash::Sha256.into(), }), @@ -434,6 +360,8 @@ fn export_rsa_private_key_matches_import() { } let key_name = String::from("export_rsa_private_key_matches_import"); + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_encrypt().set_decrypt().set_export(); let decoded_key = base64::decode(PRIVATE_KEY).unwrap(); client @@ -444,18 +372,7 @@ fn export_rsa_private_key_matches_import() { key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: true, - encrypt: true, - decrypt: true, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: AsymmetricEncryption::RsaPkcs1v15Crypt.into(), }, }, diff --git a/e2e_tests/tests/per_provider/normal_tests/export_public_key.rs b/e2e_tests/tests/per_provider/normal_tests/export_public_key.rs index 6bcf2e94..28efb9b5 100644 --- a/e2e_tests/tests/per_provider/normal_tests/export_public_key.rs +++ b/e2e_tests/tests/per_provider/normal_tests/export_public_key.rs @@ -134,23 +134,14 @@ fn check_export_rsa_public_possible() -> Result<()> { if !client.is_operation_supported(Opcode::PsaExportPublicKey) { return Ok(()); } + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_hash(); let key_attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: true, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), @@ -175,6 +166,8 @@ fn check_export_ecc_public_possible() -> Result<()> { if !client.is_operation_supported(Opcode::PsaExportPublicKey) { return Ok(()); } + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_hash(); let key_attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::EccKeyPair { @@ -182,18 +175,7 @@ fn check_export_ecc_public_possible() -> Result<()> { }, bits: 256, policy: Policy { - usage_flags: UsageFlags { - sign_hash: true, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { hash_alg: Hash::Sha256.into(), }), diff --git a/e2e_tests/tests/per_provider/normal_tests/import_key.rs b/e2e_tests/tests/per_provider/normal_tests/import_key.rs index 8f0989a2..8fc12b5f 100644 --- a/e2e_tests/tests/per_provider/normal_tests/import_key.rs +++ b/e2e_tests/tests/per_provider/normal_tests/import_key.rs @@ -227,24 +227,14 @@ fn check_format_import2() -> Result<()> { modulus: IntegerAsn1::from_bytes_be_unsigned(example_modulus_1024()), public_exponent: IntegerAsn1::from_bytes_be_unsigned(vec![0x01, 0x00, 0x01]), }; - + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_verify_hash().set_verify_message(); let attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::RsaPublicKey, bits: 0, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: true, - sign_message: false, - verify_message: true, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), @@ -277,24 +267,14 @@ fn check_format_import3() -> Result<()> { modulus: IntegerAsn1::from_bytes_be_unsigned(vec![0xDE; 1024]), public_exponent: IntegerAsn1::from_bytes_be_unsigned(vec![0x01, 0x00, 0x01]), }; - + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_verify_hash().set_verify_message(); let attributes = Attributes { lifetime: Lifetime::Persistent, key_type: Type::RsaPublicKey, bits: 1023, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: true, - sign_message: false, - verify_message: true, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), @@ -329,25 +309,15 @@ fn failed_imported_key_should_be_removed() -> Result<()> { modulus: IntegerAsn1::from_bytes_be_unsigned(example_modulus_1024()), public_exponent: IntegerAsn1::from_bytes_be_unsigned(vec![0x01, 0x00, 0x01]), }; - + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_verify_hash().set_verify_message(); let attributes = Attributes { lifetime: Lifetime::Persistent, // Not supported key_type: Type::Aes, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: true, - sign_message: false, - verify_message: true, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), @@ -370,7 +340,8 @@ fn failed_imported_key_should_be_removed() -> Result<()> { fn import_key_pair() { let mut client = TestClient::new(); let key_name = String::from("failed_imported_key_should_be_removed"); - + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_hash().set_sign_message().set_verify_hash().set_verify_message(); client .import_key( key_name, @@ -379,18 +350,7 @@ fn import_key_pair() { key_type: Type::RsaKeyPair, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - export: false, - copy: false, - cache: false, - encrypt: false, - decrypt: false, - sign_message: true, - sign_hash: true, - verify_message: true, - verify_hash: true, - derive: false, - }, + usage_flags, permitted_algorithms: Algorithm::AsymmetricSignature( AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), diff --git a/e2e_tests/tests/per_provider/normal_tests/key_attributes.rs b/e2e_tests/tests/per_provider/normal_tests/key_attributes.rs index 80e87208..447c03c0 100644 --- a/e2e_tests/tests/per_provider/normal_tests/key_attributes.rs +++ b/e2e_tests/tests/per_provider/normal_tests/key_attributes.rs @@ -29,23 +29,14 @@ fn wrong_type() { Algorithm::AsymmetricSignature(AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), }); + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_hash(); let key_attributes = Attributes { lifetime: Lifetime::Persistent, key_type, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: true, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: permitted_algorithm, }, }; @@ -76,24 +67,14 @@ fn wrong_usage_flags() { Algorithm::AsymmetricSignature(AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), }); + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_verify_hash(); let key_attributes = Attributes { lifetime: Lifetime::Persistent, key_type, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - // Forbid signing - sign_hash: false, - verify_hash: true, - sign_message: false, - verify_message: false, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: permitted_algorithm, }, }; @@ -164,23 +145,14 @@ fn wrong_permitted_algorithm() { Algorithm::AsymmetricSignature(AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha512.into(), }); + let mut usage_flags: UsageFlags = Default::default(); + let _ = usage_flags.set_sign_hash(); let key_attributes = Attributes { lifetime: Lifetime::Persistent, key_type, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: true, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: permitted_algorithm, }, }; @@ -212,23 +184,13 @@ fn no_usage_flag_set() { Algorithm::AsymmetricSignature(AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha512.into(), }); + let usage_flags: UsageFlags = Default::default(); let key_attributes = Attributes { lifetime: Lifetime::Persistent, key_type, bits: 1024, policy: Policy { - usage_flags: UsageFlags { - sign_hash: false, - verify_hash: false, - sign_message: false, - verify_message: false, - export: false, - encrypt: false, - decrypt: false, - cache: false, - copy: false, - derive: false, - }, + usage_flags, permitted_algorithms: permitted_algorithm, }, }; diff --git a/e2e_tests/tests/per_provider/normal_tests/mod.rs b/e2e_tests/tests/per_provider/normal_tests/mod.rs index ac995299..d3b72c40 100644 --- a/e2e_tests/tests/per_provider/normal_tests/mod.rs +++ b/e2e_tests/tests/per_provider/normal_tests/mod.rs @@ -14,3 +14,4 @@ mod import_key; mod key_agreement; mod key_attributes; mod ping; +mod capability_discovery; diff --git a/src/back/backend_handler.rs b/src/back/backend_handler.rs index ef5317d3..3b7c5663 100644 --- a/src/back/backend_handler.rs +++ b/src/back/backend_handler.rs @@ -278,6 +278,14 @@ impl BackEndHandler { trace!("psa_verify_message egress"); self.result_to_response(NativeResult::PsaVerifyMessage(result), header) } + NativeOperation::CanDoCrypto(op_can_do_crypto) => { + let app = unwrap_or_else_return!(app.ok_or(ResponseStatus::NotAuthenticated)); + let result = unwrap_or_else_return!(self + .provider + .can_do_crypto(app.into(), op_can_do_crypto)); + trace!("can_do_crypto egress"); + self.result_to_response(NativeResult::CanDoCrypto(result), header) + } } } } diff --git a/src/providers/mod.rs b/src/providers/mod.rs index 0b9afeb1..80c3bc8b 100644 --- a/src/providers/mod.rs +++ b/src/providers/mod.rs @@ -31,11 +31,11 @@ pub mod trusted_service; use crate::authenticators::ApplicationName; use parsec_interface::operations::{ - delete_client, list_authenticators, list_clients, list_keys, list_opcodes, list_providers, - ping, psa_aead_decrypt, psa_aead_encrypt, psa_asymmetric_decrypt, psa_asymmetric_encrypt, - psa_destroy_key, psa_export_key, psa_export_public_key, psa_generate_key, psa_generate_random, - psa_hash_compare, psa_hash_compute, psa_import_key, psa_raw_key_agreement, psa_sign_hash, - psa_sign_message, psa_verify_hash, psa_verify_message, + can_do_crypto, delete_client, list_authenticators, list_clients, list_keys, list_opcodes, + list_providers, ping, psa_aead_decrypt, psa_aead_encrypt, psa_asymmetric_decrypt, + psa_asymmetric_encrypt, psa_destroy_key, psa_export_key, psa_export_public_key, + psa_generate_key, psa_generate_random, psa_hash_compare, psa_hash_compute, psa_import_key, + psa_raw_key_agreement, psa_sign_hash, psa_sign_message, psa_verify_hash, psa_verify_message, }; use parsec_interface::requests::{ResponseStatus, Result}; @@ -296,4 +296,14 @@ pub trait Provide { trace!("psa_verify_message ingress"); Err(ResponseStatus::PsaErrorNotSupported) } + + ///Get the filtered list of supported algorithms. + fn can_do_crypto( + &self, + _app_name: ApplicationName, + _op: can_do_crypto::Operation, + ) -> Result { + trace!("can_do_crypto ingress"); + Err(ResponseStatus::PsaErrorNotSupported) + } } diff --git a/src/providers/pkcs11/capability_discovery.rs b/src/providers/pkcs11/capability_discovery.rs new file mode 100644 index 00000000..4295be90 --- /dev/null +++ b/src/providers/pkcs11/capability_discovery.rs @@ -0,0 +1,109 @@ +#![allow(unused)] +use super::Provider; +use crate::authenticators::ApplicationName; +use crate::providers::pkcs11::to_response_status; +use cryptoki::types::mechanism::Mechanism; +use cryptoki::types::mechanism::MechanismInfo; +use cryptoki::types::mechanism::MechanismType; +use log::trace; +use parsec_interface::operations::can_do_crypto; +use parsec_interface::operations::can_do_crypto::CheckType; +use parsec_interface::operations::psa_algorithm::Algorithm; +use parsec_interface::operations::psa_key_attributes::EccFamily; +use parsec_interface::operations::psa_key_attributes::Type; +use parsec_interface::requests::ResponseStatus::{PsaErrorNotSupported, Success}; +use parsec_interface::requests::Result; +use std::convert::TryFrom; +use std::ops::Deref; + +impl Provider { + pub(super) fn can_do_crypto_internal( + &self, + _app_name: ApplicationName, + op: can_do_crypto::Operation, + ) -> Result { + let attributes = op.attributes; + let check_type = op.check_type; + if attributes.key_type + == (Type::EccKeyPair { + curve_family: EccFamily::SecpR1, + }) + || attributes.key_type + == (Type::EccPublicKey { + curve_family: EccFamily::SecpR1, + }) + { + if !(attributes.bits == 192 + || attributes.bits == 224 + || attributes.bits == 256 + || attributes.bits == 384 + || attributes.bits == 512) + { + return Err(PsaErrorNotSupported); + } + } else if !(attributes.key_type == Type::RsaKeyPair + || attributes.key_type == Type::RsaPublicKey) + { + return Err(PsaErrorNotSupported); + } + if check_type == CheckType::Generate { + if !(attributes.key_type == Type::RsaKeyPair + || attributes.key_type + == (Type::EccKeyPair { + curve_family: EccFamily::SecpR1, + })) + { + return Err(PsaErrorNotSupported); + } + } + if check_type == CheckType::Import { + if !(attributes.key_type == Type::RsaPublicKey + || attributes.key_type + == (Type::EccPublicKey { + curve_family: EccFamily::SecpR1, + })) + { + return Err(PsaErrorNotSupported); + } + } + if attributes.policy.permitted_algorithms != Algorithm::None { + let supported_mechanisms: Vec = self + .backend + .get_mechanism_list(self.slot_number) + .map_err(to_response_status)?; + let mechanism = Mechanism::try_from(attributes.policy.permitted_algorithms) + .map_err(to_response_status)?; + let mechanism_info: MechanismInfo = self + .backend + .get_mechanism_info(self.slot_number, mechanism.mechanism_type()) + .map_err(to_response_status)?; + if !(supported_mechanisms.contains(&mechanism.mechanism_type())) { + return Err(PsaErrorNotSupported); + } + if !(mechanism_info.min_key_size().deref() <= &(attributes.bits as u64) + && &(attributes.bits as u64) <= mechanism_info.max_key_size().deref()) + { + return Err(PsaErrorNotSupported); + } + if check_type == CheckType::Use { + if !(attributes.policy.usage_flags.decrypt() + || attributes.policy.usage_flags.encrypt() + || attributes.policy.usage_flags.sign_hash() + || attributes.policy.usage_flags.sign_message() + || attributes.policy.usage_flags.verify_hash() + || attributes.policy.usage_flags.verify_message()) + { + return Err(PsaErrorNotSupported); + } + } + } else { + if check_type == CheckType::Use { + return Err(PsaErrorNotSupported); + } + } + if check_type == CheckType::Derive { + return Err(PsaErrorNotSupported); + } + return Ok(can_do_crypto::Result {}); + } +} diff --git a/src/providers/pkcs11/mod.rs b/src/providers/pkcs11/mod.rs index 48ef1514..b981809a 100644 --- a/src/providers/pkcs11/mod.rs +++ b/src/providers/pkcs11/mod.rs @@ -14,11 +14,11 @@ use cryptoki::types::Flags; use cryptoki::Pkcs11; use derivative::Derivative; use log::{error, info, trace, warn}; -use parsec_interface::operations::{list_clients, list_keys, list_providers::ProviderInfo}; use parsec_interface::operations::{ - psa_asymmetric_decrypt, psa_asymmetric_encrypt, psa_destroy_key, psa_export_public_key, - psa_generate_key, psa_import_key, psa_sign_hash, psa_verify_hash, + can_do_crypto, psa_asymmetric_decrypt, psa_asymmetric_encrypt, psa_destroy_key, + psa_export_public_key, psa_generate_key, psa_import_key, psa_sign_hash, psa_verify_hash, }; +use parsec_interface::operations::{list_clients, list_keys, list_providers::ProviderInfo}; use parsec_interface::requests::{Opcode, ProviderId, ResponseStatus, Result}; use parsec_interface::secrecy::{ExposeSecret, SecretString}; use std::collections::HashSet; @@ -34,11 +34,12 @@ type LocalIdStore = HashSet; mod asym_encryption; mod asym_sign; +mod capability_discovery; mod key_management; mod key_metadata; mod utils; -const SUPPORTED_OPCODES: [Opcode; 8] = [ +const SUPPORTED_OPCODES: [Opcode; 9] = [ Opcode::PsaGenerateKey, Opcode::PsaDestroyKey, Opcode::PsaSignHash, @@ -47,6 +48,7 @@ const SUPPORTED_OPCODES: [Opcode; 8] = [ Opcode::PsaExportPublicKey, Opcode::PsaAsymmetricDecrypt, Opcode::PsaAsymmetricEncrypt, + Opcode::CanDoCrypto, ]; /// Provider for Public Key Cryptography Standard #11 @@ -325,6 +327,15 @@ impl Provide for Provider { trace!("psa_asymmetric_decrypt ingress"); self.psa_asymmetric_decrypt_internal(app_name, op) } + + fn can_do_crypto( + &self, + app_name: ApplicationName, + op: can_do_crypto::Operation, + ) -> Result { + trace!("can_do_crypto ingress"); + self.can_do_crypto_internal(app_name, op) + } } /// Builder for Pkcs11Provider diff --git a/src/providers/pkcs11/utils.rs b/src/providers/pkcs11/utils.rs index 33359e3d..8ba52bcc 100644 --- a/src/providers/pkcs11/utils.rs +++ b/src/providers/pkcs11/utils.rs @@ -85,18 +85,18 @@ pub fn key_pair_usage_flags_to_pkcs11_attributes( priv_template: &mut Vec, ) { priv_template.push(Attribute::Sign( - (usage_flags.sign_hash || usage_flags.sign_message).into(), + (usage_flags.sign_hash() || usage_flags.sign_message()).into(), )); pub_template.push(Attribute::Verify( - (usage_flags.verify_hash || usage_flags.verify_message).into(), + (usage_flags.verify_hash() || usage_flags.verify_message()).into(), )); - pub_template.push(Attribute::Encrypt((usage_flags.encrypt).into())); - priv_template.push(Attribute::Decrypt((usage_flags.decrypt).into())); - priv_template.push(Attribute::Derive((usage_flags.derive).into())); - priv_template.push(Attribute::Extractable((usage_flags.export).into())); - priv_template.push(Attribute::Sensitive((usage_flags.export).into())); - priv_template.push(Attribute::Copyable((usage_flags.copy).into())); - pub_template.push(Attribute::Copyable((usage_flags.copy).into())); + pub_template.push(Attribute::Encrypt((usage_flags.encrypt()).into())); + priv_template.push(Attribute::Decrypt((usage_flags.decrypt()).into())); + priv_template.push(Attribute::Derive((usage_flags.derive()).into())); + priv_template.push(Attribute::Extractable((usage_flags.export()).into())); + priv_template.push(Attribute::Sensitive((usage_flags.export()).into())); + priv_template.push(Attribute::Copyable((usage_flags.copy()).into())); + pub_template.push(Attribute::Copyable((usage_flags.copy()).into())); } /// Format the input data into ASN1 DigestInfo bytes