diff --git a/cryptoki/src/object.rs b/cryptoki/src/object.rs index 5b40b352..393fb487 100644 --- a/cryptoki/src/object.rs +++ b/cryptoki/src/object.rs @@ -4,7 +4,7 @@ use crate::error::{Error, Result}; use crate::mechanism::MechanismType; -use crate::types::{Bbool, Date, Ulong}; +use crate::types::{Date, Ulong}; use cryptoki_sys::*; use log::error; use std::convert::TryFrom; @@ -412,9 +412,9 @@ pub enum Attribute { /// List of mechanisms allowed to be used with the key AllowedMechanisms(Vec), /// Indicates that the user has to supply the PIN for each use with the key - AlwaysAuthenticate(Bbool), + AlwaysAuthenticate(bool), /// Indicates if the key has always had the Sensitive attribute set to true - AlwaysSensitive(Bbool), + AlwaysSensitive(bool), /// Description of the application that manages the object Application(Vec), /// BER-encoding of a sequence of object identifier values @@ -430,19 +430,19 @@ pub enum Attribute { /// The CRT coefficient `iqmp` of an RSA private key Coefficient(Vec), /// Determines if an object can be copied - Copyable(Bbool), + Copyable(bool), /// Determines if a key supports decryption - Decrypt(Bbool), + Decrypt(bool), /// Determines if it is possible to derive other keys from the key - Derive(Bbool), + Derive(bool), /// Determines if it is possible to destroy an object - Destroyable(Bbool), + Destroyable(bool), /// Parameters describing an elliptic curve EcParams(Vec), /// Elliptic Curve point EcPoint(Vec), /// Determines if a key supports encryption - Encrypt(Bbool), + Encrypt(bool), /// The end date of the object EndDate(Date), /// The private exponent `dmp1` of an RSA private key @@ -450,7 +450,7 @@ pub enum Attribute { /// The private exponent `dmq1` of an RSA private key Exponent2(Vec), /// Determines if a key is extractable and can be wrapped - Extractable(Bbool), + Extractable(bool), /// Hash of issuer public key HashOfIssuerPublicKey(Vec), /// Hash of subject public key @@ -466,15 +466,15 @@ pub enum Attribute { /// Description of the object Label(Vec), /// Indicates if the key was generated locally or copied from a locally created object - Local(Bbool), + Local(bool), /// Determines if the object can be modified - Modifiable(Bbool), + Modifiable(bool), /// Modulus value of a key Modulus(Vec), /// Length in bits of the modulus of a key ModulusBits(Ulong), /// Indicates if the key has never had the Extractable attribute set to true - NeverExtractable(Bbool), + NeverExtractable(bool), /// Object ID ObjectId(Vec), /// DER encoding of the attribute certificate's subject field @@ -486,7 +486,7 @@ pub enum Attribute { /// The prime `q` of an RSA private key Prime2(Vec), /// Determines if the object is private - Private(Bbool), + Private(bool), /// The private exponent `d` PrivateExponent(Vec), /// Public exponent value of a key @@ -494,23 +494,23 @@ pub enum Attribute { /// DER-encoding of the SubjectPublicKeyInfo PublicKeyInfo(Vec), /// Determines if the key is sensitive - Sensitive(Bbool), + Sensitive(bool), /// DER encoding of the certificate serial number SerialNumber(Vec), /// Determines if a key supports signing - Sign(Bbool), + Sign(bool), /// Determines if a key supports signing where the data can be recovered from the signature - SignRecover(Bbool), + SignRecover(bool), /// The start date of the object StartDate(Date), /// DER-encoding of certificate subject name Subject(Vec), /// Determines if the object is a token object - Token(Bbool), + Token(bool), /// Determines if an object is trusted - Trusted(Bbool), + Trusted(bool), /// Determines if a key supports unwrapping - Unwrap(Bbool), + Unwrap(bool), /// Gives the URL where the complete certificate can ber obtained Url(Vec), /// Value of the object @@ -518,13 +518,13 @@ pub enum Attribute { /// Length in bytes of the value ValueLen(Ulong), /// Determines if a key supports verifying - Verify(Bbool), + Verify(bool), /// Determines if a key supports verifying where the data can be recovered from the signature - VerifyRecover(Bbool), + VerifyRecover(bool), /// Determines if a key supports wrapping - Wrap(Bbool), + Wrap(bool), /// Indicates that the key can only be wrapped with a wrapping key that has the Trusted attribute - WrapWithTrusted(Bbool), + WrapWithTrusted(bool), } impl Attribute { @@ -617,7 +617,7 @@ impl Attribute { | Attribute::Verify(_) | Attribute::VerifyRecover(_) | Attribute::Wrap(_) - | Attribute::WrapWithTrusted(_) => 1, + | Attribute::WrapWithTrusted(_) => std::mem::size_of::(), Attribute::Base(_) => 1, Attribute::Application(bytes) | Attribute::Label(bytes) | Attribute::Url(bytes) => { std::mem::size_of::() * bytes.len() @@ -669,6 +669,10 @@ impl Attribute { /// will not use Attribute parameters but return them /// directly to the caller. fn ptr(&self) -> *mut c_void { + // Note: bools in Rust are guaranteed to occupy a byte, so + // &mut bool as a raw pointer will provide the same space + // needed for CK_BBOOL types. See also: + // https://doc.rust-lang.org/reference/type-layout.html#primitive-data-layout match self { // CK_BBOOL Attribute::AlwaysAuthenticate(b) @@ -755,6 +759,19 @@ impl From<&Attribute> for CK_ATTRIBUTE { } } +/// Private function standing in for TryInto for &[u8] +/// which can't be implemented through the actual trait because +/// it and both types are external to this crate. +/// NB from the specification: "In Cryptoki, the CK_BBOOL data type +/// is a Boolean type that can be true or false. A zero value means +/// false, and a nonzero value means true." so there is no invalid +/// byte value. +fn try_u8_into_bool(slice: &[u8]) -> Result { + let as_array: [u8; std::mem::size_of::()] = slice.try_into()?; + let as_byte = CK_BBOOL::from_ne_bytes(as_array); + Ok(!matches!(as_byte, 0u8)) +} + impl TryFrom for Attribute { type Error = Error; @@ -769,28 +786,36 @@ impl TryFrom for Attribute { }; match attr_type { // CK_BBOOL - AttributeType::AlwaysAuthenticate => Ok(Attribute::AlwaysAuthenticate(val.try_into()?)), - AttributeType::AlwaysSensitive => Ok(Attribute::AlwaysSensitive(val.try_into()?)), - AttributeType::Copyable => Ok(Attribute::Copyable(val.try_into()?)), - AttributeType::Decrypt => Ok(Attribute::Decrypt(val.try_into()?)), - AttributeType::Derive => Ok(Attribute::Derive(val.try_into()?)), - AttributeType::Destroyable => Ok(Attribute::Destroyable(val.try_into()?)), - AttributeType::Encrypt => Ok(Attribute::Encrypt(val.try_into()?)), - AttributeType::Extractable => Ok(Attribute::Extractable(val.try_into()?)), - AttributeType::Local => Ok(Attribute::Local(val.try_into()?)), - AttributeType::Modifiable => Ok(Attribute::Modifiable(val.try_into()?)), - AttributeType::NeverExtractable => Ok(Attribute::NeverExtractable(val.try_into()?)), - AttributeType::Private => Ok(Attribute::Private(val.try_into()?)), - AttributeType::Sensitive => Ok(Attribute::Sensitive(val.try_into()?)), - AttributeType::Sign => Ok(Attribute::Sign(val.try_into()?)), - AttributeType::SignRecover => Ok(Attribute::SignRecover(val.try_into()?)), - AttributeType::Token => Ok(Attribute::Token(val.try_into()?)), - AttributeType::Trusted => Ok(Attribute::Trusted(val.try_into()?)), - AttributeType::Unwrap => Ok(Attribute::Unwrap(val.try_into()?)), - AttributeType::Verify => Ok(Attribute::Verify(val.try_into()?)), - AttributeType::VerifyRecover => Ok(Attribute::VerifyRecover(val.try_into()?)), - AttributeType::Wrap => Ok(Attribute::Wrap(val.try_into()?)), - AttributeType::WrapWithTrusted => Ok(Attribute::WrapWithTrusted(val.try_into()?)), + AttributeType::AlwaysAuthenticate => { + Ok(Attribute::AlwaysAuthenticate(try_u8_into_bool(val)?)) + } + AttributeType::AlwaysSensitive => { + Ok(Attribute::AlwaysSensitive(try_u8_into_bool(val)?)) + } + AttributeType::Copyable => Ok(Attribute::Copyable(try_u8_into_bool(val)?)), + AttributeType::Decrypt => Ok(Attribute::Decrypt(try_u8_into_bool(val)?)), + AttributeType::Derive => Ok(Attribute::Derive(try_u8_into_bool(val)?)), + AttributeType::Destroyable => Ok(Attribute::Destroyable(try_u8_into_bool(val)?)), + AttributeType::Encrypt => Ok(Attribute::Encrypt(try_u8_into_bool(val)?)), + AttributeType::Extractable => Ok(Attribute::Extractable(try_u8_into_bool(val)?)), + AttributeType::Local => Ok(Attribute::Local(try_u8_into_bool(val)?)), + AttributeType::Modifiable => Ok(Attribute::Modifiable(try_u8_into_bool(val)?)), + AttributeType::NeverExtractable => { + Ok(Attribute::NeverExtractable(try_u8_into_bool(val)?)) + } + AttributeType::Private => Ok(Attribute::Private(try_u8_into_bool(val)?)), + AttributeType::Sensitive => Ok(Attribute::Sensitive(try_u8_into_bool(val)?)), + AttributeType::Sign => Ok(Attribute::Sign(try_u8_into_bool(val)?)), + AttributeType::SignRecover => Ok(Attribute::SignRecover(try_u8_into_bool(val)?)), + AttributeType::Token => Ok(Attribute::Token(try_u8_into_bool(val)?)), + AttributeType::Trusted => Ok(Attribute::Trusted(try_u8_into_bool(val)?)), + AttributeType::Unwrap => Ok(Attribute::Unwrap(try_u8_into_bool(val)?)), + AttributeType::Verify => Ok(Attribute::Verify(try_u8_into_bool(val)?)), + AttributeType::VerifyRecover => Ok(Attribute::VerifyRecover(try_u8_into_bool(val)?)), + AttributeType::Wrap => Ok(Attribute::Wrap(try_u8_into_bool(val)?)), + AttributeType::WrapWithTrusted => { + Ok(Attribute::WrapWithTrusted(try_u8_into_bool(val)?)) + } // CK_ULONG AttributeType::ModulusBits => Ok(Attribute::ModulusBits( CK_ULONG::from_ne_bytes(val.try_into()?).try_into()?, diff --git a/cryptoki/src/types.rs b/cryptoki/src/types.rs index 05c50e45..cae0a905 100644 --- a/cryptoki/src/types.rs +++ b/cryptoki/src/types.rs @@ -4,7 +4,6 @@ use crate::error::{Error, Result}; use cryptoki_sys::*; -use log::error; use std::convert::TryFrom; use std::convert::TryInto; use std::fmt::Formatter; @@ -36,64 +35,6 @@ pub(crate) trait Flags: std::fmt::Display { } } -#[repr(u8)] -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -/// Byte-sized boolean -pub enum Bbool { - /// False value - False = 0, - /// True value - True = 1, -} - -impl TryFrom<&[u8]> for Bbool { - type Error = Error; - - fn try_from(slice: &[u8]) -> Result { - CK_BBOOL::from_ne_bytes(slice.try_into()?).try_into() - } -} - -impl From for CK_BBOOL { - fn from(bbool: Bbool) -> Self { - bbool as CK_BBOOL - } -} - -impl From for Bbool { - fn from(val: bool) -> Self { - if val { - Bbool::True - } else { - Bbool::False - } - } -} - -impl From for bool { - fn from(val: Bbool) -> Self { - match val { - Bbool::False => false, - Bbool::True => true, - } - } -} - -impl TryFrom for Bbool { - type Error = Error; - - fn try_from(bbool: CK_BBOOL) -> Result { - match bbool { - CK_FALSE => Ok(Bbool::False), - CK_TRUE => Ok(Bbool::True), - other => { - error!("Bbool value {} is invalid.", other); - Err(Error::InvalidValue) - } - } - } -} - #[derive(Debug, Copy, Clone)] #[repr(transparent)] /// Value that represents a date diff --git a/cryptoki/tests/basic.rs b/cryptoki/tests/basic.rs index 34a65cef..eace90fa 100644 --- a/cryptoki/tests/basic.rs +++ b/cryptoki/tests/basic.rs @@ -47,14 +47,14 @@ fn sign_verify() -> Result<()> { // pub key template let pub_key_template = vec![ - Attribute::Token(true.into()), - Attribute::Private(false.into()), + Attribute::Token(true), + Attribute::Private(false), Attribute::PublicExponent(public_exponent), Attribute::ModulusBits(modulus_bits.into()), ]; // priv key template - let priv_key_template = vec![Attribute::Token(true.into())]; + let priv_key_template = vec![Attribute::Token(true)]; // generate a key pair let (public, private) = @@ -99,18 +99,15 @@ fn encrypt_decrypt() -> Result<()> { // pub key template let pub_key_template = vec![ - Attribute::Token(true.into()), - Attribute::Private(false.into()), + Attribute::Token(true), + Attribute::Private(false), Attribute::PublicExponent(public_exponent), Attribute::ModulusBits(modulus_bits.into()), - Attribute::Encrypt(true.into()), + Attribute::Encrypt(true), ]; // priv key template - let priv_key_template = vec![ - Attribute::Token(true.into()), - Attribute::Decrypt(true.into()), - ]; + let priv_key_template = vec![Attribute::Token(true), Attribute::Decrypt(true)]; // generate a key pair let (public, private) = @@ -157,22 +154,22 @@ fn derive_key() -> Result<()> { // pub key template let pub_key_template = vec![ - Attribute::Token(true.into()), - Attribute::Private(false.into()), - Attribute::Derive(true.into()), + Attribute::Token(true), + Attribute::Private(false), + Attribute::Derive(true), Attribute::KeyType(KeyType::EC), - Attribute::Verify(true.into()), + Attribute::Verify(true), Attribute::EcParams(secp256r1_oid), ]; // priv key template let priv_key_template = vec![ - Attribute::Token(true.into()), - Attribute::Private(true.into()), - Attribute::Sensitive(true.into()), - Attribute::Extractable(false.into()), - Attribute::Derive(true.into()), - Attribute::Sign(true.into()), + Attribute::Token(true), + Attribute::Private(true), + Attribute::Sensitive(true), + Attribute::Extractable(false), + Attribute::Derive(true), + Attribute::Sign(true), ]; // generate a key pair @@ -206,9 +203,9 @@ fn derive_key() -> Result<()> { &[ Attribute::Class(ObjectClass::SECRET_KEY), Attribute::KeyType(KeyType::GENERIC_SECRET), - Attribute::Sensitive(false.into()), - Attribute::Extractable(true.into()), - Attribute::Token(false.into()), + Attribute::Sensitive(false), + Attribute::Extractable(true), + Attribute::Token(false), ], )?; @@ -249,13 +246,13 @@ fn import_export() -> Result<()> { let modulus = vec![0xFF; 1024]; let template = vec![ - Attribute::Token(true.into()), - Attribute::Private(false.into()), + Attribute::Token(true), + Attribute::Private(false), Attribute::PublicExponent(public_exponent), Attribute::Modulus(modulus.clone()), Attribute::Class(ObjectClass::PUBLIC_KEY), Attribute::KeyType(KeyType::RSA), - Attribute::Verify(true.into()), + Attribute::Verify(true), ]; { @@ -316,10 +313,10 @@ fn wrap_and_unwrap_key() { session.login(UserType::User, Some(USER_PIN)).unwrap(); let key_to_be_wrapped_template = vec![ - Attribute::Token(true.into()), + Attribute::Token(true), // the key needs to be extractable to be suitable for being wrapped - Attribute::Extractable(true.into()), - Attribute::Encrypt(true.into()), + Attribute::Extractable(true), + Attribute::Encrypt(true), ]; // generate a secret key that will be wrapped @@ -339,16 +336,16 @@ fn wrap_and_unwrap_key() { // pub key template let pub_key_template = vec![ - Attribute::Token(true.into()), - Attribute::Private(true.into()), + Attribute::Token(true), + Attribute::Private(true), Attribute::PublicExponent(vec![0x01, 0x00, 0x01]), Attribute::ModulusBits(1024.into()), // key needs to have "wrap" attribute to wrap other keys - Attribute::Wrap(true.into()), + Attribute::Wrap(true), ]; // priv key template - let priv_key_template = vec![Attribute::Token(true.into())]; + let priv_key_template = vec![Attribute::Token(true)]; let (wrapping_key, unwrapping_key) = session .generate_key_pair( @@ -369,9 +366,9 @@ fn wrap_and_unwrap_key() { unwrapping_key, &wrapped_key, &[ - Attribute::Token(true.into()), - Attribute::Private(true.into()), - Attribute::Encrypt(true.into()), + Attribute::Token(true), + Attribute::Private(true), + Attribute::Encrypt(true), Attribute::Class(ObjectClass::SECRET_KEY), Attribute::KeyType(KeyType::DES3), ], @@ -603,17 +600,17 @@ fn get_attribute_info_test() -> Result<()> { // pub key template let pub_key_template = vec![ - Attribute::Token(false.into()), - Attribute::Private(false.into()), + Attribute::Token(false), + Attribute::Private(false), Attribute::PublicExponent(public_exponent), Attribute::ModulusBits(modulus_bits.into()), ]; // priv key template let priv_key_template = vec![ - Attribute::Token(false.into()), - Attribute::Sensitive(true.into()), - Attribute::Extractable(false.into()), + Attribute::Token(false), + Attribute::Sensitive(true), + Attribute::Extractable(false), ]; // generate a key pair