Skip to content

Add support for Pkcs#11 Profile objects #304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 118 additions & 4 deletions cryptoki/src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -331,6 +334,7 @@ impl From<AttributeType> 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,
Expand Down Expand Up @@ -405,6 +409,7 @@ impl TryFrom<CK_ATTRIBUTE_TYPE> 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),
Expand Down Expand Up @@ -526,6 +531,8 @@ pub enum Attribute {
Private(bool),
/// The private exponent `d`
PrivateExponent(Vec<u8>),
/// The Profile ID
ProfileId(ProfileIdType),
/// Public exponent value of a key
PublicExponent(Vec<u8>),
/// DER-encoding of the SubjectPublicKeyInfo
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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::<CK_PROFILE_ID>(),
Attribute::PublicExponent(bytes) => bytes.len(),
Attribute::PublicKeyInfo(bytes) => bytes.len(),
Attribute::Seed(bytes) => bytes.len(),
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -922,6 +932,9 @@ impl TryFrom<CK_ATTRIBUTE> 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(),
})),
Expand Down Expand Up @@ -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 {
Expand All @@ -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})"),
}
}
Expand Down Expand Up @@ -1329,6 +1350,8 @@ impl TryFrom<CK_OBJECT_CLASS> 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);
Expand Down Expand Up @@ -1708,3 +1731,94 @@ impl TryFrom<CK_CERTIFICATE_TYPE> 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:
///
/// <https://docs.oasis-open.org/pkcs11/pkcs11-profiles/v3.1/os/pkcs11-profiles-v3.1-os.html>
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<ProfileIdType> for CK_PROFILE_ID {
fn from(profile_id: ProfileIdType) -> Self {
*profile_id
}
}

impl TryFrom<CK_PROFILE_ID> for ProfileIdType {
type Error = Error;

fn try_from(profile_id: CK_PROFILE_ID) -> Result<Self> {
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)
}
}
}
}
4 changes: 2 additions & 2 deletions cryptoki/src/session/object_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ObjectHandleIterator> {
pub fn iter_objects(&self, template: &[Attribute]) -> Result<ObjectHandleIterator<'_>> {
self.iter_objects_with_cache_size(template, MAX_OBJECT_COUNT)
}

Expand All @@ -248,7 +248,7 @@ impl Session {
&self,
template: &[Attribute],
cache_size: NonZeroUsize,
) -> Result<ObjectHandleIterator> {
) -> Result<ObjectHandleIterator<'_>> {
let template: Vec<CK_ATTRIBUTE> = template.iter().map(Into::into).collect();
ObjectHandleIterator::new(self, template, cache_size)
}
Expand Down
Loading