From f13e011227529e4d30d1e057879c38dc698cbb0c Mon Sep 17 00:00:00 2001 From: Sam Davis Date: Fri, 10 Sep 2021 16:57:42 +0100 Subject: [PATCH] Added the CanDoCrypto operation as well as fixing some of the other test scripts Added the internal CanDoCrypto as a new capability_discovery file in the pkcs11 provider and made corresponding changes to the relevent files. Also added the end to end tests for CanDoCrypto and fixed the other tests that were still using the old syntax for the usage flags. Signed-off-by: Sam Davis --- Cargo.toml | 6 +- e2e_tests/Cargo.toml | 2 +- e2e_tests/src/lib.rs | 258 ++++-------- .../normal_tests/asym_encryption.rs | 30 +- .../normal_tests/asym_sign_verify.rs | 104 +---- .../normal_tests/capability_discovery.rs | 371 ++++++++++++++++++ .../normal_tests/create_destroy_key.rs | 15 +- .../per_provider/normal_tests/export_key.rs | 133 ++----- .../normal_tests/export_public_key.rs | 30 +- .../per_provider/normal_tests/import_key.rs | 64 +-- .../normal_tests/key_attributes.rs | 60 +-- .../tests/per_provider/normal_tests/mod.rs | 1 + src/back/backend_handler.rs | 8 + src/providers/mod.rs | 20 +- src/providers/pkcs11/capability_discovery.rs | 109 +++++ src/providers/pkcs11/mod.rs | 19 +- src/providers/pkcs11/utils.rs | 18 +- 17 files changed, 693 insertions(+), 555 deletions(-) create mode 100644 e2e_tests/tests/per_provider/normal_tests/capability_discovery.rs create mode 100644 src/providers/pkcs11/capability_discovery.rs 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