From 82d883ee20be0c6ed8fe31e965e384d3250055d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Gonz=C3=A1lez?= Date: Fri, 8 Sep 2023 11:59:51 +0100 Subject: [PATCH] Update cryptoki and cryptoki-sys crates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update the cryptoki and cryptoki-sys crates. * Remove the psa-crypto-conversions feature from the cryptoki dependency in the Cargo.toml file. The psa-crypto crate is already being brought up in the Cargo.toml file and this would have lead to a crate conflict when upgrading. * Remove parsec's dependency on cryptoki's psa-crypto by creating helping functions to perform type conversions. * Minor changes to the code to update according to the updates version of cryptoki. Signed-off-by: Tomás González --- Cargo.lock | 30 +++++++--- Cargo.toml | 2 +- e2e_tests/Cargo.toml | 2 +- e2e_tests/tests/all_providers/config/mod.rs | 21 ++++--- fuzz/Cargo.lock | 30 +++++++--- src/providers/pkcs11/asym_encryption.rs | 9 +-- src/providers/pkcs11/asym_sign.rs | 9 +-- src/providers/pkcs11/capability_discovery.rs | 14 ++--- src/providers/pkcs11/key_management.rs | 6 +- src/providers/pkcs11/mod.rs | 20 +++---- src/providers/pkcs11/utils.rs | 60 ++++++++++++++++++-- 11 files changed, 141 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ea7acd5..166299f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -248,22 +248,23 @@ dependencies = [ [[package]] name = "cryptoki" -version = "0.3.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "570006e51d08ec89ce5bbfdcf428ad96111636d524bf2447bee6377fd0e1d889" +checksum = "95d9fb68c88020896fa3741a10e41f206b2ace927724170a753a3f2ba5f77c2b" dependencies = [ + "bitflags", "cryptoki-sys", - "derivative", "libloading", "log", - "psa-crypto", + "paste", + "secrecy 0.8.0", ] [[package]] name = "cryptoki-sys" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d12231889cbf7e11d2965a063d9518bc7aac60c5b125dc61c8ff2111a160eae" +checksum = "4bc9943e09928a84ed6e76dbaea1699b7678e95b2487b0de31075af300221095" dependencies = [ "libloading", "target-lexicon", @@ -1014,7 +1015,7 @@ dependencies = [ "num-traits", "prost", "psa-crypto", - "secrecy", + "secrecy 0.7.0", "serde", "uuid", "zeroize", @@ -1057,6 +1058,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "peeking_take_while" version = "0.1.2" @@ -1498,6 +1505,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "zeroize", +] + [[package]] name = "semver" version = "0.11.0" diff --git a/Cargo.toml b/Cargo.toml index 2790cd7d..84eb89b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 = { version = "0.3.1", optional = true, features = ["psa-crypto-conversions"] } +cryptoki = { version = "0.5.0", optional = true, default-features = false } picky-asn1-der = { version = "0.4.0", optional = true } picky-asn1 = { version = "0.7.2", optional = true } tss-esapi = { version = "7.2.0", optional = true } diff --git a/e2e_tests/Cargo.toml b/e2e_tests/Cargo.toml index 1212d077..2ddb9a3b 100644 --- a/e2e_tests/Cargo.toml +++ b/e2e_tests/Cargo.toml @@ -30,7 +30,7 @@ picky-asn1 = "0.3.1" sha2 = "0.9.3" serial_test = "0.5.1" regex = "1.6.0" -cryptoki = "0.3.1" +cryptoki = { version = "0.5.0", default-features = false } snailquote = "0.3.1" [features] diff --git a/e2e_tests/tests/all_providers/config/mod.rs b/e2e_tests/tests/all_providers/config/mod.rs index f028e635..528cd898 100644 --- a/e2e_tests/tests/all_providers/config/mod.rs +++ b/e2e_tests/tests/all_providers/config/mod.rs @@ -1,5 +1,6 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 +use cryptoki::types::AuthPin; use e2e_tests::auto_test_keyname; use e2e_tests::TestClient; use log::{error, info}; @@ -456,7 +457,6 @@ fn activate_cred_no_auth() { #[cfg(feature = "pkcs11-provider")] fn init_pkcs11_token(lib: &str, so_pin: &str, pin: &str) -> String { use cryptoki::context::{CInitializeArgs, Pkcs11}; - use cryptoki::session::SessionFlags; use cryptoki::session::UserType; use std::path::Path; @@ -464,19 +464,22 @@ fn init_pkcs11_token(lib: &str, so_pin: &str, pin: &str) -> String { // // initialize the library pkcs11.initialize(CInitializeArgs::OsThreads).unwrap(); let slot = pkcs11.get_slots_with_token().unwrap().pop().unwrap(); - pkcs11.init_token(slot, so_pin, "Test Token").unwrap(); - // set flags - let mut flags = SessionFlags::new(); - let _ = flags.set_rw_session(true).set_serial_session(true); + pkcs11 + .init_token(slot, &AuthPin::new(so_pin.to_string()), "Test Token") + .unwrap(); // open a session - let session = pkcs11.open_session_no_callback(slot, flags).unwrap(); + let session = pkcs11.open_rw_session(slot).unwrap(); // log in the session - session.login(UserType::So, Some(so_pin)).unwrap(); - session.init_pin(pin).unwrap(); + session + .login(UserType::So, Some(&AuthPin::new(so_pin.to_string()))) + .unwrap(); + session.init_pin(&AuthPin::new(pin.to_string())).unwrap(); // get the token serial number let token = pkcs11.get_token_info(slot).unwrap(); pkcs11.finalize(); - std::str::from_utf8(&token.serialNumber).unwrap().to_owned() + std::str::from_utf8(token.serial_number().as_bytes()) + .unwrap() + .to_owned() } #[cfg(feature = "pkcs11-provider")] diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 3046f10c..1142f7f7 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -278,22 +278,23 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "cryptoki" -version = "0.3.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "570006e51d08ec89ce5bbfdcf428ad96111636d524bf2447bee6377fd0e1d889" +checksum = "95d9fb68c88020896fa3741a10e41f206b2ace927724170a753a3f2ba5f77c2b" dependencies = [ + "bitflags", "cryptoki-sys", - "derivative", "libloading", "log", - "psa-crypto", + "paste", + "secrecy 0.8.0", ] [[package]] name = "cryptoki-sys" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d12231889cbf7e11d2965a063d9518bc7aac60c5b125dc61c8ff2111a160eae" +checksum = "4bc9943e09928a84ed6e76dbaea1699b7678e95b2487b0de31075af300221095" dependencies = [ "libloading", "target-lexicon", @@ -1053,7 +1054,7 @@ dependencies = [ "num-traits", "prost", "psa-crypto", - "secrecy", + "secrecy 0.7.0", "serde", "uuid", "zeroize", @@ -1091,6 +1092,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "peeking_take_while" version = "0.1.2" @@ -1467,6 +1474,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "zeroize", +] + [[package]] name = "semver" version = "0.11.0" diff --git a/src/providers/pkcs11/asym_encryption.rs b/src/providers/pkcs11/asym_encryption.rs index c91c8fe0..458930f7 100644 --- a/src/providers/pkcs11/asym_encryption.rs +++ b/src/providers/pkcs11/asym_encryption.rs @@ -1,18 +1,16 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 -use super::utils::to_response_status; +use super::utils::{algorithm_to_mechanism, to_response_status}; use super::KeyPairType; use super::Provider; use crate::authenticators::ApplicationIdentity; use crate::key_info_managers::KeyIdentity; use cryptoki::error::Error; use cryptoki::error::RvError; -use cryptoki::mechanism::Mechanism; use log::{info, trace}; use parsec_interface::operations::psa_algorithm::{Algorithm, AsymmetricEncryption}; use parsec_interface::operations::{psa_asymmetric_decrypt, psa_asymmetric_encrypt}; use parsec_interface::requests::{ResponseStatus, Result}; -use std::convert::TryFrom; impl Provider { pub(super) fn psa_asymmetric_encrypt_internal( @@ -30,7 +28,7 @@ impl Provider { op.validate(key_attributes)?; - let mech = Mechanism::try_from(Algorithm::from(op.alg)).map_err(to_response_status)?; + let mech = algorithm_to_mechanism(Algorithm::from(op.alg)).map_err(to_response_status)?; let session = self.new_session()?; @@ -60,8 +58,7 @@ impl Provider { let key_attributes = self.key_info_store.get_key_attributes(&key_identity)?; op.validate(key_attributes)?; - - let mech = Mechanism::try_from(Algorithm::from(op.alg)).map_err(to_response_status)?; + let mech = algorithm_to_mechanism(Algorithm::from(op.alg)).map_err(to_response_status)?; let session = self.new_session()?; diff --git a/src/providers/pkcs11/asym_sign.rs b/src/providers/pkcs11/asym_sign.rs index 9ec69cb5..7d0521be 100644 --- a/src/providers/pkcs11/asym_sign.rs +++ b/src/providers/pkcs11/asym_sign.rs @@ -1,17 +1,15 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 -use super::utils::to_response_status; +use super::utils::{algorithm_to_mechanism, to_response_status}; use super::Provider; use super::{utils, KeyPairType}; use crate::authenticators::ApplicationIdentity; use crate::key_info_managers::KeyIdentity; -use cryptoki::mechanism::Mechanism; use log::{info, trace}; use parsec_interface::operations::psa_algorithm::Algorithm; use parsec_interface::operations::psa_key_attributes::Type; use parsec_interface::operations::{psa_sign_hash, psa_verify_hash}; use parsec_interface::requests::{ResponseStatus, Result}; -use std::convert::TryFrom; impl Provider { pub(super) fn psa_sign_hash_internal( @@ -30,7 +28,7 @@ impl Provider { op.validate(key_attributes)?; - let mech = Mechanism::try_from(Algorithm::from(op.alg)).map_err(to_response_status)?; + let mech = algorithm_to_mechanism(Algorithm::from(op.alg)).map_err(to_response_status)?; let session = self.new_session()?; @@ -68,8 +66,7 @@ impl Provider { let key_attributes = self.key_info_store.get_key_attributes(&key_identity)?; op.validate(key_attributes)?; - - let mech = Mechanism::try_from(Algorithm::from(op.alg)).map_err(to_response_status)?; + let mech = algorithm_to_mechanism(Algorithm::from(op.alg)).map_err(to_response_status)?; let session = self.new_session()?; diff --git a/src/providers/pkcs11/capability_discovery.rs b/src/providers/pkcs11/capability_discovery.rs index cdeb3c03..d98d7b5f 100644 --- a/src/providers/pkcs11/capability_discovery.rs +++ b/src/providers/pkcs11/capability_discovery.rs @@ -2,11 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 #![allow(trivial_numeric_casts)] +use super::utils::algorithm_to_mechanism; use super::{utils, Provider}; use crate::authenticators::ApplicationIdentity; use crate::providers::crypto_capability::CanDoCrypto; use crate::providers::pkcs11::to_response_status; -use cryptoki::mechanism::{Mechanism, MechanismInfo, MechanismType}; +use cryptoki::mechanism::{MechanismInfo, MechanismType}; use cryptoki::types::Ulong; use log::{info, trace}; use parsec_interface::operations::can_do_crypto; @@ -14,7 +15,6 @@ use parsec_interface::operations::psa_algorithm::*; use parsec_interface::operations::psa_key_attributes::{Attributes, Type}; use parsec_interface::requests::ResponseStatus::PsaErrorNotSupported; use parsec_interface::requests::Result; -use std::convert::TryFrom; impl CanDoCrypto for Provider { fn can_do_crypto_internal( @@ -65,7 +65,7 @@ impl CanDoCrypto for Provider { .backend .get_mechanism_list(self.slot_number) .map_err(to_response_status)?; - let mechanism = Mechanism::try_from(attributes.policy.permitted_algorithms) + let mechanism = algorithm_to_mechanism(attributes.policy.permitted_algorithms) .map_err(to_response_status)?; if !(supported_mechanisms.contains(&mechanism.mechanism_type())) { info!("Mechanism {:?} is not supported", mechanism); @@ -77,8 +77,8 @@ impl CanDoCrypto for Provider { .get_mechanism_info(self.slot_number, mechanism.mechanism_type()) .map_err(to_response_status)?; if std::any::type_name::() == std::any::type_name::() { - if !((attributes.bits as u64) >= (*mechanism_info.min_key_size()).into() - && (attributes.bits as u64) <= (*mechanism_info.max_key_size()).into()) + if !((attributes.bits as u64) >= (mechanism_info.min_key_size() as u64) + && (attributes.bits as u64) <= (mechanism_info.max_key_size()) as u64) { info!( "Incorrect key size {} for mechanism {:?}", @@ -87,8 +87,8 @@ impl CanDoCrypto for Provider { return Err(PsaErrorNotSupported); } } else { - if !((attributes.bits as u64) >= (*mechanism_info.min_key_size() as u64) - && (attributes.bits as u64) <= (*mechanism_info.max_key_size() as u64)) + if !((attributes.bits as u64) >= (mechanism_info.min_key_size() as u64) + && (attributes.bits as u64) <= (mechanism_info.max_key_size() as u64)) { info!( "Incorrect key size {} for mechanism {:?}", diff --git a/src/providers/pkcs11/key_management.rs b/src/providers/pkcs11/key_management.rs index 5c5df2a2..b6bb0b4c 100644 --- a/src/providers/pkcs11/key_management.rs +++ b/src/providers/pkcs11/key_management.rs @@ -1,6 +1,6 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 -use super::utils::to_response_status; +use super::utils::{algorithm_to_mechanism, to_response_status}; use super::{utils, KeyPairType, Provider}; use crate::authenticators::ApplicationIdentity; use crate::key_info_managers::KeyIdentity; @@ -17,7 +17,7 @@ use parsec_interface::requests::{ResponseStatus, Result}; use parsec_interface::secrecy::ExposeSecret; use picky_asn1::wrapper::{IntegerAsn1, OctetStringAsn1}; use picky_asn1_x509::RsaPublicKey; -use std::convert::{TryFrom, TryInto}; +use std::convert::TryInto; impl Provider { /// Find the PKCS 11 object handle corresponding to the key ID and the key type (public, @@ -117,7 +117,7 @@ impl Provider { let mut pub_template = vec![ Attribute::Id(key_id.to_be_bytes().to_vec()), Attribute::Token(true.into()), - Attribute::AllowedMechanisms(vec![Mechanism::try_from( + Attribute::AllowedMechanisms(vec![algorithm_to_mechanism( key_attributes.policy.permitted_algorithms, ) .map_err(to_response_status)? diff --git a/src/providers/pkcs11/mod.rs b/src/providers/pkcs11/mod.rs index 6cd2b563..7153c1a7 100644 --- a/src/providers/pkcs11/mod.rs +++ b/src/providers/pkcs11/mod.rs @@ -11,8 +11,9 @@ use crate::providers::crypto_capability::CanDoCrypto; use crate::providers::ProviderIdentity; use cryptoki::context::{CInitializeArgs, Pkcs11}; use cryptoki::error::{Error as Pkcs11Error, RvError}; -use cryptoki::session::{Session, SessionFlags, UserType}; +use cryptoki::session::{Session, UserType}; use cryptoki::slot::Slot; +use cryptoki::types::AuthPin; use derivative::Derivative; use log::{error, info, trace, warn}; use parsec_interface::operations::{ @@ -211,12 +212,9 @@ impl Provider { // * logged in if the pin is set // * set on the slot in the provider fn new_session(&self) -> Result { - let mut flags = SessionFlags::new(); - let _ = flags.set_rw_session(true).set_serial_session(true); - let session = self .backend - .open_session_no_callback(self.slot_number, flags) + .open_rw_session(self.slot_number) .map_err(to_response_status)?; if self.user_pin.is_some() { @@ -231,7 +229,7 @@ impl Provider { } session - .login(UserType::User, Some(&pin)) + .login(UserType::User, Some(&AuthPin::new(pin.to_string()))) .or_else(|e| { if let Pkcs11Error::Pkcs11(RvError::UserAlreadyLoggedIn) = e { Ok(()) @@ -529,11 +527,11 @@ impl ProviderBuilder { format_error!("Failed parsing token info", e); Error::new(ErrorKind::InvalidData, "Failed parsing token info") })?; - let sn = - String::from_utf8(current_token.serialNumber.to_vec()).map_err(|e| { - format_error!("Failed parsing token serial number", e); - Error::new(ErrorKind::InvalidData, "Failed parsing token serial number") - })?; + let sn = String::from_utf8(current_token.serial_number().as_bytes().to_vec()) + .map_err(|e| { + format_error!("Failed parsing token serial number", e); + Error::new(ErrorKind::InvalidData, "Failed parsing token serial number") + })?; if sn.trim() == serial_number.trim() { slot = Some(current_slot); break; diff --git a/src/providers/pkcs11/utils.rs b/src/providers/pkcs11/utils.rs index 3009f95c..6dca554c 100644 --- a/src/providers/pkcs11/utils.rs +++ b/src/providers/pkcs11/utils.rs @@ -1,18 +1,21 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 use cryptoki::error::{Error, RvError}; +use cryptoki::mechanism::rsa; +use cryptoki::mechanism::Mechanism; use cryptoki::object::Attribute; use log::error; use parsec_interface::operations::psa_algorithm::*; use parsec_interface::operations::psa_key_attributes::*; use parsec_interface::requests::ResponseStatus; -use parsec_interface::requests::Result; +use parsec_interface::requests::Result as ResponseResult; use picky_asn1::wrapper::ObjectIdentifierAsn1; use picky_asn1_x509::{ algorithm_identifier::EcParameters, AlgorithmIdentifier, DigestInfo, ShaVariant, }; +use psa_crypto::types::algorithm::Algorithm; +use psa_crypto::types::algorithm::Hash; use std::convert::TryInto; - // Public exponent value for all RSA keys. pub const PUBLIC_EXPONENT: [u8; 3] = [0x01, 0x00, 0x01]; @@ -99,7 +102,7 @@ pub fn key_pair_usage_flags_to_pkcs11_attributes( } /// Format the input data into ASN1 DigestInfo bytes -pub fn digest_info(alg: AsymmetricSignature, hash: Vec) -> Result> { +pub fn digest_info(alg: AsymmetricSignature, hash: Vec) -> ResponseResult> { let oid = match alg { AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: SignHash::Specific(Hash::Sha224), @@ -123,7 +126,7 @@ pub fn digest_info(alg: AsymmetricSignature, hash: Vec) -> Result> { .map_err(|_| ResponseStatus::PsaErrorGenericError) } -pub fn ec_params(ecc_family: EccFamily, bits: usize) -> Result { +pub fn ec_params(ecc_family: EccFamily, bits: usize) -> ResponseResult { Ok(EcParameters::NamedCurve(match (ecc_family, bits) { // The following "unwrap()" should be ok, as they cover constant conversions (EccFamily::SecpR1, 192) => { @@ -144,3 +147,52 @@ pub fn ec_params(ecc_family: EccFamily, bits: usize) -> Result { _ => return Err(ResponseStatus::PsaErrorNotSupported), })) } + +#[allow(deprecated)] +/// Convert a PSA Crypto Hash algorithm to a MGF type +pub fn pkcsmgftype_from_psa_crypto_hash(alg: Hash) -> Result { + match alg { + Hash::Sha1 => Ok(rsa::PkcsMgfType::MGF1_SHA1), + Hash::Sha224 => Ok(rsa::PkcsMgfType::MGF1_SHA224), + Hash::Sha256 => Ok(rsa::PkcsMgfType::MGF1_SHA256), + Hash::Sha384 => Ok(rsa::PkcsMgfType::MGF1_SHA384), + Hash::Sha512 => Ok(rsa::PkcsMgfType::MGF1_SHA512), + alg => { + error!("{:?} is not a supported MGF1 algorithm", alg); + Err(Error::NotSupported) + } + } +} + +#[allow(deprecated)] +pub fn algorithm_to_mechanism(alg: Algorithm) -> Result, Error> { + match alg { + Algorithm::Hash(Hash::Sha1) => Ok(Mechanism::Sha1), + Algorithm::Hash(Hash::Sha256) => Ok(Mechanism::Sha256), + Algorithm::Hash(Hash::Sha384) => Ok(Mechanism::Sha384), + Algorithm::Hash(Hash::Sha512) => Ok(Mechanism::Sha512), + Algorithm::AsymmetricSignature(AsymmetricSignature::RsaPkcs1v15Sign { .. }) + | Algorithm::AsymmetricEncryption(AsymmetricEncryption::RsaPkcs1v15Crypt { .. }) => { + Ok(Mechanism::RsaPkcs) + } + Algorithm::AsymmetricSignature(AsymmetricSignature::RsaPss { + hash_alg: SignHash::Specific(hash_alg), + }) => Ok(Mechanism::RsaPkcsPss(rsa::PkcsPssParams { + hash_alg: algorithm_to_mechanism(Algorithm::from(hash_alg))?.mechanism_type(), + mgf: pkcsmgftype_from_psa_crypto_hash(hash_alg)?, + s_len: hash_alg.hash_length().try_into()?, + })), + Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { .. }) => Ok(Mechanism::Ecdsa), + Algorithm::AsymmetricEncryption(AsymmetricEncryption::RsaOaep { hash_alg }) => { + Ok(Mechanism::RsaPkcsOaep(rsa::PkcsOaepParams::new( + algorithm_to_mechanism(Algorithm::from(hash_alg))?.mechanism_type(), + pkcsmgftype_from_psa_crypto_hash(hash_alg)?, + rsa::PkcsOaepSource::empty(), + ))) + } + alg => { + error!("{:?} is not a supported algorithm", alg); + Err(Error::NotSupported) + } + } +}