Skip to content

Commit

Permalink
Update cryptoki and cryptoki-sys crates
Browse files Browse the repository at this point in the history
 * 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 <[email protected]>
  • Loading branch information
tgonzalezorlandoarm committed Sep 12, 2023
1 parent 34b45f3 commit 6c13f83
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 47 deletions.
30 changes: 23 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
6 changes: 1 addition & 5 deletions e2e_tests/tests/all_providers/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,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;

Expand All @@ -465,11 +464,8 @@ fn init_pkcs11_token(lib: &str, so_pin: &str, pin: &str) -> String {
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);
// 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();
Expand Down
9 changes: 3 additions & 6 deletions src/providers/pkcs11/asym_encryption.rs
Original file line number Diff line number Diff line change
@@ -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(
Expand All @@ -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()?;

Expand Down Expand Up @@ -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()?;

Expand Down
9 changes: 3 additions & 6 deletions src/providers/pkcs11/asym_sign.rs
Original file line number Diff line number Diff line change
@@ -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(
Expand All @@ -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()?;

Expand Down Expand Up @@ -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()?;

Expand Down
15 changes: 7 additions & 8 deletions src/providers/pkcs11/capability_discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@
// SPDX-License-Identifier: Apache-2.0

#![allow(trivial_numeric_casts)]
use super::utils::{algorithm_to_mechanism, to_response_status};
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;
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(
Expand Down Expand Up @@ -65,7 +64,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);
Expand All @@ -77,8 +76,8 @@ impl CanDoCrypto for Provider {
.get_mechanism_info(self.slot_number, mechanism.mechanism_type())
.map_err(to_response_status)?;
if std::any::type_name::<Ulong>() == std::any::type_name::<u64>() {
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 {:?}",
Expand All @@ -87,8 +86,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 {:?}",
Expand Down
6 changes: 3 additions & 3 deletions src/providers/pkcs11/key_management.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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,
Expand Down Expand Up @@ -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)?
Expand Down
12 changes: 5 additions & 7 deletions src/providers/pkcs11/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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<Session> {
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() {
Expand All @@ -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(())
Expand Down Expand Up @@ -530,7 +528,7 @@ impl ProviderBuilder {
Error::new(ErrorKind::InvalidData, "Failed parsing token info")
})?;
let sn =
String::from_utf8(current_token.serialNumber.to_vec()).map_err(|e| {
String::from_utf8(current_token.serial_number().into()).map_err(|e| {
format_error!("Failed parsing token serial number", e);
Error::new(ErrorKind::InvalidData, "Failed parsing token serial number")
})?;
Expand Down
60 changes: 56 additions & 4 deletions src/providers/pkcs11/utils.rs
Original file line number Diff line number Diff line change
@@ -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];

Expand Down Expand Up @@ -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<u8>) -> Result<Vec<u8>> {
pub fn digest_info(alg: AsymmetricSignature, hash: Vec<u8>) -> ResponseResult<Vec<u8>> {
let oid = match alg {
AsymmetricSignature::RsaPkcs1v15Sign {
hash_alg: SignHash::Specific(Hash::Sha224),
Expand All @@ -123,7 +126,7 @@ pub fn digest_info(alg: AsymmetricSignature, hash: Vec<u8>) -> Result<Vec<u8>> {
.map_err(|_| ResponseStatus::PsaErrorGenericError)
}

pub fn ec_params(ecc_family: EccFamily, bits: usize) -> Result<EcParameters> {
pub fn ec_params(ecc_family: EccFamily, bits: usize) -> ResponseResult<EcParameters> {
Ok(EcParameters::NamedCurve(match (ecc_family, bits) {
// The following "unwrap()" should be ok, as they cover constant conversions
(EccFamily::SecpR1, 192) => {
Expand All @@ -144,3 +147,52 @@ pub fn ec_params(ecc_family: EccFamily, bits: usize) -> Result<EcParameters> {
_ => 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<rsa::PkcsMgfType, Error> {
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<Mechanism<'static>, 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)
}
}
}

0 comments on commit 6c13f83

Please sign in to comment.