Skip to content

Commit

Permalink
Use rust's own bool type in abstraction crate
Browse files Browse the repository at this point in the history
The Bbool type was translating between the FFI's CK_BBOOL and
rust's own bool, by providing a backing intermediate type. But
the storage for a bool is guaranteed to be large enough for the
job, and the point of conversion from byte back to bool is
already structured to check for validity.

Signed-off-by: Keith Koskie <[email protected]>
  • Loading branch information
vkkoskie committed Nov 5, 2021
1 parent abd872a commit d2a795a
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 105 deletions.
120 changes: 74 additions & 46 deletions cryptoki/src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -412,9 +412,9 @@ pub enum Attribute {
/// List of mechanisms allowed to be used with the key
AllowedMechanisms(Vec<MechanismType>),
/// 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<u8>),
/// BER-encoding of a sequence of object identifier values
Expand All @@ -430,27 +430,27 @@ pub enum Attribute {
/// The CRT coefficient `iqmp` of an RSA private key
Coefficient(Vec<u8>),
/// 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<u8>),
/// Elliptic Curve point
EcPoint(Vec<u8>),
/// 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
Exponent1(Vec<u8>),
/// The private exponent `dmq1` of an RSA private key
Exponent2(Vec<u8>),
/// Determines if a key is extractable and can be wrapped
Extractable(Bbool),
Extractable(bool),
/// Hash of issuer public key
HashOfIssuerPublicKey(Vec<u8>),
/// Hash of subject public key
Expand All @@ -466,15 +466,15 @@ pub enum Attribute {
/// Description of the object
Label(Vec<u8>),
/// 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<u8>),
/// 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<u8>),
/// DER encoding of the attribute certificate's subject field
Expand All @@ -486,45 +486,45 @@ pub enum Attribute {
/// The prime `q` of an RSA private key
Prime2(Vec<u8>),
/// Determines if the object is private
Private(Bbool),
Private(bool),
/// The private exponent `d`
PrivateExponent(Vec<u8>),
/// Public exponent value of a key
PublicExponent(Vec<u8>),
/// DER-encoding of the SubjectPublicKeyInfo
PublicKeyInfo(Vec<u8>),
/// Determines if the key is sensitive
Sensitive(Bbool),
Sensitive(bool),
/// DER encoding of the certificate serial number
SerialNumber(Vec<u8>),
/// 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<u8>),
/// 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<u8>),
/// Value of the object
Value(Vec<u8>),
/// 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 {
Expand Down Expand Up @@ -617,7 +617,7 @@ impl Attribute {
| Attribute::Verify(_)
| Attribute::VerifyRecover(_)
| Attribute::Wrap(_)
| Attribute::WrapWithTrusted(_) => 1,
| Attribute::WrapWithTrusted(_) => std::mem::size_of::<bool>(),
Attribute::Base(_) => 1,
Attribute::Application(bytes) | Attribute::Label(bytes) | Attribute::Url(bytes) => {
std::mem::size_of::<CK_UTF8CHAR>() * bytes.len()
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -755,6 +759,22 @@ impl From<&Attribute> for CK_ATTRIBUTE {
}
}

/// Private function standing in for TryInto<bool> for &[u8]
/// which can't be implemented through the actual trait because
/// it and both types are external to this crate.
fn try_u8_into_bool(slice: &[u8]) -> Result<bool> {
let as_array: [u8; std::mem::size_of::<CK_BBOOL>()] = slice.try_into()?;
let as_byte = CK_BBOOL::from_ne_bytes(as_array);
match as_byte {
0u8 => Ok(false),
1u8 => Ok(true),
other => {
error!("Byte value {} invalid as bool.", other);
Err(Error::InvalidValue)
}
}
}

impl TryFrom<CK_ATTRIBUTE> for Attribute {
type Error = Error;

Expand All @@ -769,28 +789,36 @@ impl TryFrom<CK_ATTRIBUTE> 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()?,
Expand Down
59 changes: 0 additions & 59 deletions cryptoki/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<Self> {
CK_BBOOL::from_ne_bytes(slice.try_into()?).try_into()
}
}

impl From<Bbool> for CK_BBOOL {
fn from(bbool: Bbool) -> Self {
bbool as CK_BBOOL
}
}

impl From<bool> for Bbool {
fn from(val: bool) -> Self {
if val {
Bbool::True
} else {
Bbool::False
}
}
}

impl From<Bbool> for bool {
fn from(val: Bbool) -> Self {
match val {
Bbool::False => false,
Bbool::True => true,
}
}
}

impl TryFrom<CK_BBOOL> for Bbool {
type Error = Error;

fn try_from(bbool: CK_BBOOL) -> Result<Self> {
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
Expand Down

0 comments on commit d2a795a

Please sign in to comment.