diff --git a/cryptoki/src/object.rs b/cryptoki/src/object.rs index 7680da3c..ab1ce944 100644 --- a/cryptoki/src/object.rs +++ b/cryptoki/src/object.rs @@ -94,6 +94,8 @@ pub enum AttributeType { ObjectId, /// DER encoding of the attribute certificate's subject field Owner, + /// Algorithm-specific parameter set + ParameterSet, /// Prime number value of a key Prime, /// The prime `p` of an RSA private key @@ -108,6 +110,10 @@ pub enum AttributeType { PublicExponent, /// DER-encoding of the SubjectPublicKeyInfo PublicKeyInfo, + /// Profile ID + ProfileId, + /// Seed to derive private key + Seed, /// Determines if the key is sensitive Sensitive, /// DER encoding of the certificate serial number @@ -144,10 +150,6 @@ pub enum AttributeType { Wrap, /// Indicates that the key can only be wrapped with a wrapping key that has the Trusted attribute WrapWithTrusted, - /// Seed to derive private key - Seed, - /// Algorithm-specific parameter set - ParameterSet, } impl AttributeType { @@ -269,6 +271,7 @@ impl AttributeType { CKA_UNIQUE_ID => String::from(stringify!(CKA_UNIQUE_ID)), CKA_SEED => String::from(stringify!(CKA_SEED)), CKA_PARAMETER_SET => String::from(stringify!(CKA_PARAMETER_SET)), + CKA_PROFILE_ID => String::from(stringify!(CKA_PROFILE_ID)), CKA_VENDOR_DEFINED..=CK_ULONG::MAX => { format!("{}_{}", stringify!(CKA_VENDOR_DEFINED), val) } @@ -331,6 +334,7 @@ impl From for CK_ATTRIBUTE_TYPE { AttributeType::Prime2 => CKA_PRIME_2, AttributeType::Private => CKA_PRIVATE, AttributeType::PrivateExponent => CKA_PRIVATE_EXPONENT, + AttributeType::ProfileId => CKA_PROFILE_ID, AttributeType::PublicExponent => CKA_PUBLIC_EXPONENT, AttributeType::PublicKeyInfo => CKA_PUBLIC_KEY_INFO, AttributeType::Seed => CKA_SEED, @@ -405,6 +409,7 @@ impl TryFrom for AttributeType { CKA_PRIME_2 => Ok(AttributeType::Prime2), CKA_PRIVATE => Ok(AttributeType::Private), CKA_PRIVATE_EXPONENT => Ok(AttributeType::PrivateExponent), + CKA_PROFILE_ID => Ok(AttributeType::ProfileId), CKA_PUBLIC_EXPONENT => Ok(AttributeType::PublicExponent), CKA_PUBLIC_KEY_INFO => Ok(AttributeType::PublicKeyInfo), CKA_SEED => Ok(AttributeType::Seed), @@ -526,6 +531,8 @@ pub enum Attribute { Private(bool), /// The private exponent `d` PrivateExponent(Vec), + /// The Profile ID + ProfileId(ProfileIdType), /// Public exponent value of a key PublicExponent(Vec), /// DER-encoding of the SubjectPublicKeyInfo @@ -618,6 +625,7 @@ impl Attribute { Attribute::Prime2(_) => AttributeType::Prime2, Attribute::Private(_) => AttributeType::Private, Attribute::PrivateExponent(_) => AttributeType::PrivateExponent, + Attribute::ProfileId(_) => AttributeType::ProfileId, Attribute::PublicExponent(_) => AttributeType::PublicExponent, Attribute::PublicKeyInfo(_) => AttributeType::PublicKeyInfo, Attribute::Seed(_) => AttributeType::Seed, @@ -698,6 +706,7 @@ impl Attribute { Attribute::Prime1(bytes) => bytes.len(), Attribute::Prime2(bytes) => bytes.len(), Attribute::PrivateExponent(bytes) => bytes.len(), + Attribute::ProfileId(_) => size_of::(), Attribute::PublicExponent(bytes) => bytes.len(), Attribute::PublicKeyInfo(bytes) => bytes.len(), Attribute::Seed(bytes) => bytes.len(), @@ -792,6 +801,7 @@ impl Attribute { | Attribute::Id(bytes) => bytes.as_ptr() as *mut c_void, // Unique types Attribute::ParameterSet(val) => val as *const _ as *mut c_void, + Attribute::ProfileId(val) => val as *const _ as *mut c_void, Attribute::CertificateType(certificate_type) => { certificate_type as *const _ as *mut c_void } @@ -922,6 +932,9 @@ impl TryFrom for Attribute { AttributeType::Value => Ok(Attribute::Value(val.to_vec())), AttributeType::Id => Ok(Attribute::Id(val.to_vec())), // Unique types + AttributeType::ProfileId => Ok(Attribute::ProfileId(ProfileIdType { + val: CK_ULONG::from_ne_bytes(val.try_into()?), + })), AttributeType::ParameterSet => Ok(Attribute::ParameterSet(ParameterSetType { val: CK_ULONG::from_ne_bytes(val.try_into()?).into(), })), @@ -1278,6 +1291,12 @@ impl ObjectClass { pub const MECHANISM: ObjectClass = ObjectClass { val: CKO_MECHANISM }; /// An OTP key object pub const OTP_KEY: ObjectClass = ObjectClass { val: CKO_OTP_KEY }; + /// Profile object + pub const PROFILE: ObjectClass = ObjectClass { val: CKO_PROFILE }; + /// Validation object + pub const VALIDATION: ObjectClass = ObjectClass { + val: CKO_VALIDATION, + }; pub(crate) fn stringify(class: CK_OBJECT_CLASS) -> String { match class { @@ -1290,6 +1309,8 @@ impl ObjectClass { CKO_DOMAIN_PARAMETERS => String::from(stringify!(CKO_DOMAIN_PARAMETERS)), CKO_MECHANISM => String::from(stringify!(CKO_MECHANISM)), CKO_OTP_KEY => String::from(stringify!(CKO_OTP_KEY)), + CKO_PROFILE => String::from(stringify!(CKO_PROFILE)), + CKO_VALIDATION => String::from(stringify!(CKO_VALIDATION)), _ => format!("unknown ({class:08x})"), } } @@ -1329,6 +1350,8 @@ impl TryFrom for ObjectClass { CKO_DOMAIN_PARAMETERS => Ok(ObjectClass::DOMAIN_PARAMETERS), CKO_MECHANISM => Ok(ObjectClass::MECHANISM), CKO_OTP_KEY => Ok(ObjectClass::OTP_KEY), + CKO_PROFILE => Ok(ObjectClass::PROFILE), + CKO_VALIDATION => Ok(ObjectClass::VALIDATION), _ => { error!("Object class {} is not supported.", object_class); @@ -1708,3 +1731,94 @@ impl TryFrom for CertificateType { } } } + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(transparent)] +/// The PKCS#11 Profile ID +/// +/// The profiles and their meaning is defined in the following document: +/// +/// +pub struct ProfileIdType { + val: CK_PROFILE_ID, +} + +impl ProfileIdType { + /// Baseline Provider + pub const BASELINE_PROFIDER: ProfileIdType = ProfileIdType { + val: CKP_BASELINE_PROVIDER, + }; + /// Extended Provider + pub const EXTENDED_PROFIDER: ProfileIdType = ProfileIdType { + val: CKP_EXTENDED_PROVIDER, + }; + /// Authentication Token Provider or Consumer + pub const AUTHENTICATION_TOKEN: ProfileIdType = ProfileIdType { + val: CKP_AUTHENTICATION_TOKEN, + }; + /// Public Certificates Token Provider or Consumer + pub const PUBLIC_CERTIFICATES_TOKEN: ProfileIdType = ProfileIdType { + val: CKP_PUBLIC_CERTIFICATES_TOKEN, + }; + /// Complete Provider + pub const COMPLETE_PROVIDER: ProfileIdType = ProfileIdType { + val: CKP_COMPLETE_PROVIDER, + }; + /// HKDF TLS Token + pub const HKDF_TLS_TOKEN: ProfileIdType = ProfileIdType { + val: CKP_HKDF_TLS_TOKEN, + }; + + pub(crate) fn stringify(profile_id: CK_PROFILE_ID) -> String { + match profile_id { + CKP_BASELINE_PROVIDER => String::from(stringify!(CKP_BASELINE_PROVIDER)), + CKP_EXTENDED_PROVIDER => String::from(stringify!(CKP_EXTENDED_PROVIDER)), + CKP_AUTHENTICATION_TOKEN => String::from(stringify!(CKP_AUTHENTICATION_TOKEN)), + CKP_PUBLIC_CERTIFICATES_TOKEN => { + String::from(stringify!(CKP_PUBLIC_CERTIFICATES_TOKEN)) + } + CKP_COMPLETE_PROVIDER => String::from(stringify!(CKP_COMPLETE_PROVIDER)), + CKP_HKDF_TLS_TOKEN => String::from(stringify!(CKP_HKDF_TLS_TOKEN)), + _ => format!("unknown ({profile_id:08x})"), + } + } +} + +impl std::fmt::Display for ProfileIdType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", ProfileIdType::stringify(self.val)) + } +} + +impl Deref for ProfileIdType { + type Target = CK_PROFILE_ID; + + fn deref(&self) -> &Self::Target { + &self.val + } +} + +impl From for CK_PROFILE_ID { + fn from(profile_id: ProfileIdType) -> Self { + *profile_id + } +} + +impl TryFrom for ProfileIdType { + type Error = Error; + + fn try_from(profile_id: CK_PROFILE_ID) -> Result { + match profile_id { + CKP_BASELINE_PROVIDER => Ok(ProfileIdType::BASELINE_PROFIDER), + CKP_EXTENDED_PROVIDER => Ok(ProfileIdType::EXTENDED_PROFIDER), + CKP_AUTHENTICATION_TOKEN => Ok(ProfileIdType::AUTHENTICATION_TOKEN), + CKP_PUBLIC_CERTIFICATES_TOKEN => Ok(ProfileIdType::PUBLIC_CERTIFICATES_TOKEN), + CKP_COMPLETE_PROVIDER => Ok(ProfileIdType::COMPLETE_PROVIDER), + CKP_HKDF_TLS_TOKEN => Ok(ProfileIdType::HKDF_TLS_TOKEN), + _ => { + error!("Profile Id {} is not supported.", profile_id); + Err(Error::NotSupported) + } + } + } +} diff --git a/cryptoki/src/session/object_management.rs b/cryptoki/src/session/object_management.rs index 3cec80d3..95ea7db7 100644 --- a/cryptoki/src/session/object_management.rs +++ b/cryptoki/src/session/object_management.rs @@ -224,7 +224,7 @@ impl Session { /// * [`ObjectHandleIterator`] for more information on how to use the iterator /// * [`Session::iter_objects_with_cache_size`] for a way to specify the cache size #[inline(always)] - pub fn iter_objects(&self, template: &[Attribute]) -> Result { + pub fn iter_objects(&self, template: &[Attribute]) -> Result> { self.iter_objects_with_cache_size(template, MAX_OBJECT_COUNT) } @@ -248,7 +248,7 @@ impl Session { &self, template: &[Attribute], cache_size: NonZeroUsize, - ) -> Result { + ) -> Result> { let template: Vec = template.iter().map(Into::into).collect(); ObjectHandleIterator::new(self, template, cache_size) }